Blame SPECS/check-password.patch

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