|
|
e4ff3b |
--- a/check_password.c 2009-10-31 18:59:06.000000000 +0100
|
|
|
e4ff3b |
+++ b/check_password.c 2014-12-17 12:25:00.148900907 +0100
|
|
|
e4ff3b |
@@ -10,7 +10,7 @@
|
|
|
e4ff3b |
#include <slap.h>
|
|
|
e4ff3b |
|
|
|
e4ff3b |
#ifdef HAVE_CRACKLIB
|
|
|
e4ff3b |
-#include "crack.h"
|
|
|
e4ff3b |
+#include <crack.h>
|
|
|
e4ff3b |
#endif
|
|
|
e4ff3b |
|
|
|
e4ff3b |
#if defined(DEBUG)
|
|
|
e4ff3b |
@@ -34,18 +34,77 @@
|
|
|
e4ff3b |
#define PASSWORD_TOO_SHORT_SZ \
|
|
|
e4ff3b |
"Password for dn=\"%s\" is too short (%d/6)"
|
|
|
e4ff3b |
#define PASSWORD_QUALITY_SZ \
|
|
|
e4ff3b |
- "Password for dn=\"%s\" does not pass required number of strength checks (%d of %d)"
|
|
|
e4ff3b |
+ "Password for dn=\"%s\" does not pass required number of strength checks for the required character sets (%d of %d)"
|
|
|
e4ff3b |
#define BAD_PASSWORD_SZ \
|
|
|
e4ff3b |
"Bad password for dn=\"%s\" because %s"
|
|
|
e4ff3b |
+#define UNKNOWN_ERROR_SZ \
|
|
|
e4ff3b |
+ "An unknown error occurred, please see your systems administrator"
|
|
|
e4ff3b |
|
|
|
e4ff3b |
typedef int (*validator) (char*);
|
|
|
e4ff3b |
-static int read_config_file (char *);
|
|
|
e4ff3b |
+static int read_config_file ();
|
|
|
e4ff3b |
static validator valid_word (char *);
|
|
|
e4ff3b |
static int set_quality (char *);
|
|
|
e4ff3b |
static int set_cracklib (char *);
|
|
|
e4ff3b |
|
|
|
e4ff3b |
int check_password (char *pPasswd, char **ppErrStr, Entry *pEntry);
|
|
|
e4ff3b |
|
|
|
e4ff3b |
+struct config_entry {
|
|
|
e4ff3b |
+ char* key;
|
|
|
e4ff3b |
+ char* value;
|
|
|
e4ff3b |
+ char* def_value;
|
|
|
e4ff3b |
+} config_entries[] = { { "minPoints", NULL, "3"},
|
|
|
e4ff3b |
+ { "useCracklib", NULL, "1"},
|
|
|
e4ff3b |
+ { "minUpper", NULL, "0"},
|
|
|
e4ff3b |
+ { "minLower", NULL, "0"},
|
|
|
e4ff3b |
+ { "minDigit", NULL, "0"},
|
|
|
e4ff3b |
+ { "minPunct", NULL, "0"},
|
|
|
e4ff3b |
+ { NULL, NULL, NULL }};
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
+int get_config_entry_int(char* entry) {
|
|
|
e4ff3b |
+ struct config_entry* centry = config_entries;
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
+ int i = 0;
|
|
|
e4ff3b |
+ char* key = centry[i].key;
|
|
|
e4ff3b |
+ while (key != NULL) {
|
|
|
e4ff3b |
+ if ( strncmp(key, entry, strlen(key)) == 0 ) {
|
|
|
e4ff3b |
+ if ( centry[i].value == NULL ) {
|
|
|
e4ff3b |
+ return atoi(centry[i].def_value);
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
+ else {
|
|
|
e4ff3b |
+ return atoi(centry[i].value);
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
+ i++;
|
|
|
e4ff3b |
+ key = centry[i].key;
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
+ return -1;
|
|
|
e4ff3b |
+}
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
+void dealloc_config_entries() {
|
|
|
e4ff3b |
+ struct config_entry* centry = config_entries;
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
+ int i = 0;
|
|
|
e4ff3b |
+ while (centry[i].key != NULL) {
|
|
|
e4ff3b |
+ if ( centry[i].value != NULL ) {
|
|
|
e4ff3b |
+ ber_memfree(centry[i].value);
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
+ i++;
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
+}
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
+char* chomp(char *s)
|
|
|
e4ff3b |
+{
|
|
|
e4ff3b |
+ char* t = ber_memalloc(strlen(s)+1);
|
|
|
e4ff3b |
+ strncpy (t,s,strlen(s)+1);
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
+ if ( t[strlen(t)-1] == '\n' ) {
|
|
|
e4ff3b |
+ t[strlen(t)-1] = '\0';
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
+ return t;
|
|
|
e4ff3b |
+}
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
static int set_quality (char *value)
|
|
|
e4ff3b |
{
|
|
|
e4ff3b |
#if defined(DEBUG)
|
|
|
e4ff3b |
@@ -84,12 +143,12 @@
|
|
|
e4ff3b |
char * parameter;
|
|
|
e4ff3b |
validator dealer;
|
|
|
e4ff3b |
} list[] = { { "minPoints", set_quality },
|
|
|
e4ff3b |
- { "useCracklib", set_cracklib },
|
|
|
e4ff3b |
- { "minUpper", set_digit },
|
|
|
e4ff3b |
- { "minLower", set_digit },
|
|
|
e4ff3b |
- { "minDigit", set_digit },
|
|
|
e4ff3b |
- { "minPunct", set_digit },
|
|
|
e4ff3b |
- { NULL, NULL } };
|
|
|
e4ff3b |
+ { "useCracklib", set_cracklib },
|
|
|
e4ff3b |
+ { "minUpper", set_digit },
|
|
|
e4ff3b |
+ { "minLower", set_digit },
|
|
|
e4ff3b |
+ { "minDigit", set_digit },
|
|
|
e4ff3b |
+ { "minPunct", set_digit },
|
|
|
e4ff3b |
+ { NULL, NULL } };
|
|
|
e4ff3b |
int index = 0;
|
|
|
e4ff3b |
|
|
|
e4ff3b |
#if defined(DEBUG)
|
|
|
e4ff3b |
@@ -98,7 +157,7 @@
|
|
|
e4ff3b |
|
|
|
e4ff3b |
while (list[index].parameter != NULL) {
|
|
|
e4ff3b |
if (strlen(word) == strlen(list[index].parameter) &&
|
|
|
e4ff3b |
- strcmp(list[index].parameter, word) == 0) {
|
|
|
e4ff3b |
+ strcmp(list[index].parameter, word) == 0) {
|
|
|
e4ff3b |
#if defined(DEBUG)
|
|
|
e4ff3b |
syslog(LOG_NOTICE, "check_password: Parameter accepted.");
|
|
|
e4ff3b |
#endif
|
|
|
e4ff3b |
@@ -114,13 +173,15 @@
|
|
|
e4ff3b |
return NULL;
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
|
|
|
e4ff3b |
-static int read_config_file (char *keyWord)
|
|
|
e4ff3b |
+static int read_config_file ()
|
|
|
e4ff3b |
{
|
|
|
e4ff3b |
FILE * config;
|
|
|
e4ff3b |
char * line;
|
|
|
e4ff3b |
int returnValue = -1;
|
|
|
e4ff3b |
|
|
|
e4ff3b |
- if ((line = ber_memcalloc(260, sizeof(char))) == NULL) {
|
|
|
e4ff3b |
+ line = ber_memcalloc(260, sizeof(char));
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
+ if ( line == NULL ) {
|
|
|
e4ff3b |
return returnValue;
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
|
|
|
e4ff3b |
@@ -133,6 +194,8 @@
|
|
|
e4ff3b |
return returnValue;
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
|
|
|
e4ff3b |
+ returnValue = 0;
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
while (fgets(line, 256, config) != NULL) {
|
|
|
e4ff3b |
char *start = line;
|
|
|
e4ff3b |
char *word, *value;
|
|
|
e4ff3b |
@@ -145,23 +208,40 @@
|
|
|
e4ff3b |
|
|
|
e4ff3b |
while (isspace(*start) && isascii(*start)) start++;
|
|
|
e4ff3b |
|
|
|
e4ff3b |
- if (! isascii(*start))
|
|
|
e4ff3b |
+ /* If we've got punctuation, just skip the line. */
|
|
|
e4ff3b |
+ if ( ispunct(*start)) {
|
|
|
e4ff3b |
+#if defined(DEBUG)
|
|
|
e4ff3b |
+ /* Debug traces to syslog. */
|
|
|
e4ff3b |
+ syslog(LOG_NOTICE, "check_password: Skipped line |%s|", line);
|
|
|
e4ff3b |
+#endif
|
|
|
e4ff3b |
continue;
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
|
|
|
e4ff3b |
- if ((word = strtok(start, " \t")) && (dealer = valid_word(word)) && (strcmp(keyWord,word)==0)) {
|
|
|
e4ff3b |
- if ((value = strtok(NULL, " \t")) == NULL)
|
|
|
e4ff3b |
- continue;
|
|
|
e4ff3b |
+ if( isascii(*start)) {
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
+ struct config_entry* centry = config_entries;
|
|
|
e4ff3b |
+ int i = 0;
|
|
|
e4ff3b |
+ char* keyWord = centry[i].key;
|
|
|
e4ff3b |
+ if ((word = strtok(start, " \t")) && (value = strtok(NULL, " \t"))) {
|
|
|
e4ff3b |
+ while ( keyWord != NULL ) {
|
|
|
e4ff3b |
+ if ((strncmp(keyWord,word,strlen(keyWord)) == 0) && (dealer = valid_word(word)) ) {
|
|
|
e4ff3b |
|
|
|
e4ff3b |
#if defined(DEBUG)
|
|
|
e4ff3b |
- syslog(LOG_NOTICE, "check_password: Word = %s, value = %s", word, value);
|
|
|
e4ff3b |
+ syslog(LOG_NOTICE, "check_password: Word = %s, value = %s", word, value);
|
|
|
e4ff3b |
#endif
|
|
|
e4ff3b |
|
|
|
e4ff3b |
- returnValue = (*dealer)(value);
|
|
|
e4ff3b |
+ centry[i].value = chomp(value);
|
|
|
e4ff3b |
+ break;
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
+ i++;
|
|
|
e4ff3b |
+ keyWord = centry[i].key;
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
-
|
|
|
e4ff3b |
fclose(config);
|
|
|
e4ff3b |
ber_memfree(line);
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
return returnValue;
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
|
|
|
e4ff3b |
@@ -170,7 +250,7 @@
|
|
|
e4ff3b |
if (curlen < nextlen + MEMORY_MARGIN) {
|
|
|
e4ff3b |
#if defined(DEBUG)
|
|
|
e4ff3b |
syslog(LOG_WARNING, "check_password: Reallocating szErrStr from %d to %d",
|
|
|
e4ff3b |
- curlen, nextlen + MEMORY_MARGIN);
|
|
|
e4ff3b |
+ curlen, nextlen + MEMORY_MARGIN);
|
|
|
e4ff3b |
#endif
|
|
|
e4ff3b |
ber_memfree(*target);
|
|
|
e4ff3b |
curlen = nextlen + MEMORY_MARGIN;
|
|
|
e4ff3b |
@@ -180,7 +260,7 @@
|
|
|
e4ff3b |
return curlen;
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
|
|
|
e4ff3b |
- int
|
|
|
e4ff3b |
+int
|
|
|
e4ff3b |
check_password (char *pPasswd, char **ppErrStr, Entry *pEntry)
|
|
|
e4ff3b |
{
|
|
|
e4ff3b |
|
|
|
e4ff3b |
@@ -210,20 +290,22 @@
|
|
|
e4ff3b |
nLen = strlen (pPasswd);
|
|
|
e4ff3b |
if ( nLen < 6) {
|
|
|
e4ff3b |
mem_len = realloc_error_message(&szErrStr, mem_len,
|
|
|
e4ff3b |
- strlen(PASSWORD_TOO_SHORT_SZ) +
|
|
|
e4ff3b |
- strlen(pEntry->e_name.bv_val) + 1);
|
|
|
e4ff3b |
+ strlen(PASSWORD_TOO_SHORT_SZ) +
|
|
|
e4ff3b |
+ strlen(pEntry->e_name.bv_val) + 1);
|
|
|
e4ff3b |
sprintf (szErrStr, PASSWORD_TOO_SHORT_SZ, pEntry->e_name.bv_val, nLen);
|
|
|
e4ff3b |
goto fail;
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
|
|
|
e4ff3b |
- /* Read config file */
|
|
|
e4ff3b |
- minQuality = read_config_file("minPoints");
|
|
|
e4ff3b |
+ if (read_config_file() == -1) {
|
|
|
e4ff3b |
+ syslog(LOG_ERR, "Warning: Could not read values from config file %s. Using defaults.", CONFIG_FILE);
|
|
|
e4ff3b |
+ }
|
|
|
e4ff3b |
|
|
|
e4ff3b |
- useCracklib = read_config_file("useCracklib");
|
|
|
e4ff3b |
- minUpper = read_config_file("minUpper");
|
|
|
e4ff3b |
- minLower = read_config_file("minLower");
|
|
|
e4ff3b |
- minDigit = read_config_file("minDigit");
|
|
|
e4ff3b |
- minPunct = read_config_file("minPunct");
|
|
|
e4ff3b |
+ minQuality = get_config_entry_int("minPoints");
|
|
|
e4ff3b |
+ useCracklib = get_config_entry_int("useCracklib");
|
|
|
e4ff3b |
+ minUpper = get_config_entry_int("minUpper");
|
|
|
e4ff3b |
+ minLower = get_config_entry_int("minLower");
|
|
|
e4ff3b |
+ minDigit = get_config_entry_int("minDigit");
|
|
|
e4ff3b |
+ minPunct = get_config_entry_int("minPunct");
|
|
|
e4ff3b |
|
|
|
e4ff3b |
/** The password must have at least minQuality strength points with one
|
|
|
e4ff3b |
* point for the first occurrance of a lower, upper, digit and
|
|
|
e4ff3b |
@@ -232,8 +314,6 @@
|
|
|
e4ff3b |
|
|
|
e4ff3b |
for ( i = 0; i < nLen; i++ ) {
|
|
|
e4ff3b |
|
|
|
e4ff3b |
- if ( nQuality >= minQuality ) break;
|
|
|
e4ff3b |
-
|
|
|
e4ff3b |
if ( islower (pPasswd[i]) ) {
|
|
|
e4ff3b |
minLower--;
|
|
|
e4ff3b |
if ( !nLower && (minLower < 1)) {
|
|
|
e4ff3b |
@@ -279,12 +359,23 @@
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
|
|
|
e4ff3b |
- if ( nQuality < minQuality ) {
|
|
|
e4ff3b |
+ /*
|
|
|
e4ff3b |
+ * If you have a required field, then it should be required in the strength
|
|
|
e4ff3b |
+ * checks.
|
|
|
e4ff3b |
+ */
|
|
|
e4ff3b |
+
|
|
|
e4ff3b |
+ if (
|
|
|
e4ff3b |
+ (minLower > 0 ) ||
|
|
|
e4ff3b |
+ (minUpper > 0 ) ||
|
|
|
e4ff3b |
+ (minDigit > 0 ) ||
|
|
|
e4ff3b |
+ (minPunct > 0 ) ||
|
|
|
e4ff3b |
+ (nQuality < minQuality)
|
|
|
e4ff3b |
+ ) {
|
|
|
e4ff3b |
mem_len = realloc_error_message(&szErrStr, mem_len,
|
|
|
e4ff3b |
- strlen(PASSWORD_QUALITY_SZ) +
|
|
|
e4ff3b |
- strlen(pEntry->e_name.bv_val) + 2);
|
|
|
e4ff3b |
+ strlen(PASSWORD_QUALITY_SZ) +
|
|
|
e4ff3b |
+ strlen(pEntry->e_name.bv_val) + 2);
|
|
|
e4ff3b |
sprintf (szErrStr, PASSWORD_QUALITY_SZ, pEntry->e_name.bv_val,
|
|
|
e4ff3b |
- nQuality, minQuality);
|
|
|
e4ff3b |
+ nQuality, minQuality);
|
|
|
e4ff3b |
goto fail;
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
|
|
|
e4ff3b |
@@ -306,7 +397,7 @@
|
|
|
e4ff3b |
for ( j = 0; j < 3; j++ ) {
|
|
|
e4ff3b |
|
|
|
e4ff3b |
snprintf (filename, FILENAME_MAXLEN - 1, "%s.%s", \
|
|
|
e4ff3b |
- CRACKLIB_DICTPATH, ext[j]);
|
|
|
e4ff3b |
+ CRACKLIB_DICTPATH, ext[j]);
|
|
|
e4ff3b |
|
|
|
e4ff3b |
if (( fp = fopen ( filename, "r")) == NULL ) {
|
|
|
e4ff3b |
|
|
|
e4ff3b |
@@ -326,9 +417,9 @@
|
|
|
e4ff3b |
r = (char *) FascistCheck (pPasswd, CRACKLIB_DICTPATH);
|
|
|
e4ff3b |
if ( r != NULL ) {
|
|
|
e4ff3b |
mem_len = realloc_error_message(&szErrStr, mem_len,
|
|
|
e4ff3b |
- strlen(BAD_PASSWORD_SZ) +
|
|
|
e4ff3b |
- strlen(pEntry->e_name.bv_val) +
|
|
|
e4ff3b |
- strlen(r));
|
|
|
e4ff3b |
+ strlen(BAD_PASSWORD_SZ) +
|
|
|
e4ff3b |
+ strlen(pEntry->e_name.bv_val) +
|
|
|
e4ff3b |
+ strlen(r));
|
|
|
e4ff3b |
sprintf (szErrStr, BAD_PASSWORD_SZ, pEntry->e_name.bv_val, r);
|
|
|
e4ff3b |
goto fail;
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
@@ -342,15 +433,15 @@
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
|
|
|
e4ff3b |
#endif
|
|
|
e4ff3b |
-
|
|
|
e4ff3b |
+ dealloc_config_entries();
|
|
|
e4ff3b |
*ppErrStr = strdup ("");
|
|
|
e4ff3b |
ber_memfree(szErrStr);
|
|
|
e4ff3b |
return (LDAP_SUCCESS);
|
|
|
e4ff3b |
|
|
|
e4ff3b |
fail:
|
|
|
e4ff3b |
+ dealloc_config_entries();
|
|
|
e4ff3b |
*ppErrStr = strdup (szErrStr);
|
|
|
e4ff3b |
ber_memfree(szErrStr);
|
|
|
e4ff3b |
return (EXIT_FAILURE);
|
|
|
e4ff3b |
|
|
|
e4ff3b |
}
|
|
|
e4ff3b |
-
|