pwdcheck-contrib.patch
application/octet-stream
Filename: pwdcheck-contrib.patch
Type: application/octet-stream
Part: 1
Message:
Re: Rejecting weak passwords
Patch
Format: context
| File | + | − |
|---|---|---|
| contrib/Makefile | 1 | 0 |
| contrib/passwordcheck/Makefile | 16 | 0 |
| contrib/passwordcheck/passwordcheck.c | 86 | 0 |
diff -r -c -N postgresql-8.5.orig/contrib/Makefile postgresql-8.5/contrib/Makefile
*** postgresql-8.5.orig/contrib/Makefile 2009-09-30 15:10:34.000000000 +0200
--- postgresql-8.5/contrib/Makefile 2009-10-09 09:38:26.000000000 +0200
***************
*** 25,30 ****
--- 25,31 ----
ltree \
oid2name \
pageinspect \
+ passwordcheck \
pg_buffercache \
pg_freespacemap \
pg_standby \
diff -r -c -N postgresql-8.5.orig/contrib/passwordcheck/Makefile postgresql-8.5/contrib/passwordcheck/Makefile
*** postgresql-8.5.orig/contrib/passwordcheck/Makefile 1970-01-01 01:00:00.000000000 +0100
--- postgresql-8.5/contrib/passwordcheck/Makefile 2009-10-09 12:18:26.000000000 +0200
***************
*** 0 ****
--- 1,16 ----
+ MODULE_big = passwordcheck
+ OBJS = passwordcheck.o
+ # uncomment the following two lines to enable cracklib support
+ # SHLIB_LINK += -lcrack
+ # CUSTOM_COPT += -DUSE_CRACKLIB
+
+ ifdef USE_PGXS
+ PG_CONFIG = pg_config
+ PGXS := $(shell $(PG_CONFIG) --pgxs)
+ include $(PGXS)
+ else
+ subdir = contrib/passwordcheck
+ top_builddir = ../..
+ include $(top_builddir)/src/Makefile.global
+ include $(top_srcdir)/contrib/contrib-global.mk
+ endif
diff -r -c -N postgresql-8.5.orig/contrib/passwordcheck/passwordcheck.c postgresql-8.5/contrib/passwordcheck/passwordcheck.c
*** postgresql-8.5.orig/contrib/passwordcheck/passwordcheck.c 1970-01-01 01:00:00.000000000 +0100
--- postgresql-8.5/contrib/passwordcheck/passwordcheck.c 2009-10-09 10:41:39.000000000 +0200
***************
*** 0 ****
--- 1,86 ----
+ #include <string.h>
+ #include <ctype.h>
+ #include "postgres.h"
+ #include "fmgr.h"
+ #include "libpq/md5.h"
+ #include "commands/user.h"
+ #ifdef USE_CRACKLIB
+ #include <crack.h>
+ #define CRACKLIB_DICTPATH "/usr/lib/cracklib_dict"
+ #endif
+
+ #ifdef PG_MODULE_MAGIC
+ PG_MODULE_MAGIC;
+ #endif
+
+ extern void _PG_init(void);
+ extern void _PG_fini(void);
+
+ /*
+ * check_password
+ * performs checks on an encrypted or unencrypted password
+ * returns 0 if the password is rejected as too weak, else 1
+ */
+ static int check_password(char * const username, char * const password) {
+ /* a password is considered encrypted if it starts with "md5" */
+ const int isencrypted = isMD5(password);
+ const int namelen = strlen(username), pwdlen = strlen(password);
+ char encrypted[MD5_PASSWD_LEN + 1];
+ int i, pwd_is_ok;
+
+ if (isencrypted) {
+ /*
+ * unfortunately we cannot perform exhaustive checks on
+ * encrypted passwords - we are restricted to guessing
+ * we check for username = password
+ */
+ if (! pg_md5_encrypt(username, username, namelen, encrypted))
+ elog(ERROR, "password encryption failed");
+
+ if (! strcmp(password, encrypted))
+ return 0;
+ } else {
+ /*
+ * for unencrypted passwords we can perform better checks
+ */
+ /* check if the password is less than 8 characters long */
+ if (pwdlen < 8)
+ return 0;
+
+ /* check if the password contains the username */
+ if (strstr(password, username))
+ return 0;
+
+ /* check if the password contains only letters */
+ pwd_is_ok = 0;
+ for (i=1; i<pwdlen; ++i) {
+ /*
+ * isalpha() does not work for multibyte encodings
+ * but let's consider non-ASCII characters safe enough
+ */
+ if (! isalpha(password[i]))
+ pwd_is_ok = 1;
+ }
+ if (! pwd_is_ok)
+ return 0;
+
+ #ifdef USE_CRACKLIB
+ /* call cracklib to check password */
+ if (FascistCheck(password, CRACKLIB_DICTPATH))
+ return 0;
+ #endif
+ }
+
+ /* all checks passed, password is ok */
+ return 1;
+ }
+
+ void _PG_init() {
+ /* activate password checks when the module is loaded */
+ check_password_hook = &check_password;
+ }
+
+ void _PG_fini() {
+ /* deactivate password check when the module is unloaded */
+ check_password_hook = NULL;
+ }