aboutsummaryrefslogtreecommitdiff
path: root/src/common/unicode/norm_test.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2017-04-07 14:56:05 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2017-04-07 14:56:05 +0300
commit60f11b87a2349985230c08616fa8a34ffde934c8 (patch)
treefe3eaa86daee5df071c4dfbc1072d89fd86ff37d /src/common/unicode/norm_test.c
parent32e33a7979a10e9fcf2c9b32703838cec1daf674 (diff)
downloadpostgresql-60f11b87a2349985230c08616fa8a34ffde934c8.tar.gz
postgresql-60f11b87a2349985230c08616fa8a34ffde934c8.zip
Use SASLprep to normalize passwords for SCRAM authentication.
An important step of SASLprep normalization, is to convert the string to Unicode normalization form NFKC. Unicode normalization requires a fairly large table of character decompositions, which is generated from data published by the Unicode consortium. The script to generate the table is put in src/common/unicode, as well test code for the normalization. A pre-generated version of the tables is included in src/include/common, so you don't need the code in src/common/unicode to build PostgreSQL, only if you wish to modify the normalization tables. The SASLprep implementation depends on the UTF-8 functions from src/backend/utils/mb/wchar.c. So to use it, you must also compile and link that. That doesn't change anything for the current users of these functions, the backend and libpq, as they both already link with wchar.o. It would be good to move those functions into a separate file in src/commmon, but I'll leave that for another day. No documentation changes included, because there is no details on the SCRAM mechanism in the docs anyway. An overview on that in the protocol specification would probably be good, even though SCRAM is documented in detail in RFC5802. I'll write that as a separate patch. An important thing to mention there is that we apply SASLprep even on invalid UTF-8 strings, to support other encodings. Patch by Michael Paquier and me. Discussion: https://www.postgresql.org/message-id/CAB7nPqSByyEmAVLtEf1KxTRh=PWNKiWKEKQR=e1yGehz=wbymQ@mail.gmail.com
Diffstat (limited to 'src/common/unicode/norm_test.c')
-rw-r--r--src/common/unicode/norm_test.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/common/unicode/norm_test.c b/src/common/unicode/norm_test.c
new file mode 100644
index 00000000000..10a370cffaf
--- /dev/null
+++ b/src/common/unicode/norm_test.c
@@ -0,0 +1,80 @@
+/*-------------------------------------------------------------------------
+ * norm_test.c
+ * Program to test Unicode normalization functions.
+ *
+ * Portions Copyright (c) 2017, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/common/unicode_norm.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres_fe.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "common/unicode_norm.h"
+
+#include "norm_test_table.h"
+
+static char *
+print_wchar_str(const pg_wchar *s)
+{
+#define BUF_DIGITS 50
+ static char buf[BUF_DIGITS * 2 + 1];
+ int i;
+
+ i = 0;
+ while (*s && i < BUF_DIGITS)
+ {
+ snprintf(&buf[i * 2], 3, "%04X", *s);
+ i++;
+ s++;
+ }
+ buf[i * 2] = '\0';
+ return buf;
+}
+
+static int
+pg_wcscmp(const pg_wchar *s1, const pg_wchar *s2)
+{
+ for (;;)
+ {
+ if (*s1 < *s2)
+ return -1;
+ if (*s1 > *s2)
+ return 1;
+ if (*s1 == 0)
+ return 0;
+ s1++;
+ s2++;
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ const pg_unicode_test *test;
+
+ for (test = UnicodeNormalizationTests; test->input[0] != 0; test++)
+ {
+ pg_wchar *result;
+
+ result = unicode_normalize_kc(test->input);
+
+ if (pg_wcscmp(test->output, result) != 0)
+ {
+ printf("FAILURE (Normalizationdata.txt line %d):\n", test->linenum);
+ printf("input:\t%s\n", print_wchar_str(test->input));
+ printf("expected:\t%s\n", print_wchar_str(test->output));
+ printf("got\t%s\n", print_wchar_str(result));
+ printf("\n");
+ exit(1);
+ }
+ }
+
+ printf("All tests successful!\n");
+ exit(0);
+}