2
* PostgreSQL type definitions for chkpass
3
* Written by D'Arcy J.M. Cain
5
* http://www.druid.net/darcy/
8
* best viewed with tabs set to 4
20
#include "utils/builtins.h"
25
* This type encrypts it's input unless the first character is a colon.
26
* The output is the encrypted form with a leading colon. The output
27
* format is designed to allow dump and reload operations to work as
28
* expected without doing special tricks.
33
* This is the internal storage format for CHKPASSs.
34
* 15 is all I need but add a little buffer
37
typedef struct chkpass
43
* Various forward declarations:
46
Datum chkpass_in(PG_FUNCTION_ARGS);
47
Datum chkpass_out(PG_FUNCTION_ARGS);
48
Datum chkpass_rout(PG_FUNCTION_ARGS);
50
/* Only equal or not equal make sense */
51
Datum chkpass_eq(PG_FUNCTION_ARGS);
52
Datum chkpass_ne(PG_FUNCTION_ARGS);
55
/* This function checks that the password is a good one
56
* It's just a placeholder for now */
58
verify_pass(const char *str)
66
PG_FUNCTION_INFO_V1(chkpass_in);
68
chkpass_in(PG_FUNCTION_ARGS)
70
char *str = PG_GETARG_CSTRING(0);
73
static char salt_chars[] =
74
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
76
/* special case to let us enter encrypted passwords */
79
result = (chkpass *) palloc(sizeof(chkpass));
80
strlcpy(result->password, str + 1, 13 + 1);
81
PG_RETURN_POINTER(result);
84
if (verify_pass(str) != 0)
86
(errcode(ERRCODE_DATA_EXCEPTION),
87
errmsg("password \"%s\" is weak", str)));
89
result = (chkpass *) palloc(sizeof(chkpass));
91
mysalt[0] = salt_chars[random() & 0x3f];
92
mysalt[1] = salt_chars[random() & 0x3f];
93
mysalt[2] = 0; /* technically the terminator is not necessary
94
* but I like to play safe */
95
strcpy(result->password, crypt(str, mysalt));
96
PG_RETURN_POINTER(result);
100
* CHKPASS output function.
101
* Just like any string but we know it is max 15 (13 plus colon and terminator.)
104
PG_FUNCTION_INFO_V1(chkpass_out);
106
chkpass_out(PG_FUNCTION_ARGS)
108
chkpass *password = (chkpass *) PG_GETARG_POINTER(0);
111
result = (char *) palloc(16);
113
strcpy(result + 1, password->password);
115
PG_RETURN_CSTRING(result);
120
* special output function that doesn't output the colon
123
PG_FUNCTION_INFO_V1(chkpass_rout);
125
chkpass_rout(PG_FUNCTION_ARGS)
127
chkpass *password = (chkpass *) PG_GETARG_POINTER(0);
129
PG_RETURN_TEXT_P(cstring_to_text(password->password));
137
PG_FUNCTION_INFO_V1(chkpass_eq);
139
chkpass_eq(PG_FUNCTION_ARGS)
141
chkpass *a1 = (chkpass *) PG_GETARG_POINTER(0);
142
text *a2 = PG_GETARG_TEXT_PP(1);
145
text_to_cstring_buffer(a2, str, sizeof(str));
146
PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) == 0);
149
PG_FUNCTION_INFO_V1(chkpass_ne);
151
chkpass_ne(PG_FUNCTION_ARGS)
153
chkpass *a1 = (chkpass *) PG_GETARG_POINTER(0);
154
text *a2 = PG_GETARG_TEXT_PP(1);
157
text_to_cstring_buffer(a2, str, sizeof(str));
158
PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) != 0);