summaryrefslogtreecommitdiff
path: root/contrib/pgcrypto/px-crypt.c
diff options
context:
space:
mode:
authorBruce Momjian2001-08-21 01:32:01 +0000
committerBruce Momjian2001-08-21 01:32:01 +0000
commitdf24cb73f6cb206837f6ef42cb13c633a61b11b8 (patch)
tree1252c4e24dd8b31aa0c337dc1f3525f494c66bd7 /contrib/pgcrypto/px-crypt.c
parent2518e273340406033e65816cff6380e20860af0e (diff)
Add missing pgcrypto file.
Diffstat (limited to 'contrib/pgcrypto/px-crypt.c')
-rw-r--r--contrib/pgcrypto/px-crypt.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c
new file mode 100644
index 00000000000..1d615a8a5a6
--- /dev/null
+++ b/contrib/pgcrypto/px-crypt.c
@@ -0,0 +1,235 @@
+/*
+ * px-crypt.c
+ * Wrapper for various crypt algorithms.
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: px-crypt.c,v 1.1 2001/08/21 01:32:01 momjian Exp $
+ */
+
+#include <postgres.h>
+#include "px-crypt.h"
+
+
+#ifndef PX_SYSTEM_CRYPT
+
+static char *
+run_crypt_des(const char *psw, const char *salt,
+ char *buf, unsigned len)
+{
+ char *res;
+
+ res = px_crypt_des(psw, salt);
+ if (strlen(res) > len - 1)
+ return NULL;
+ strcpy(buf, res);
+ return buf;
+}
+
+static char *
+run_crypt_md5(const char *psw, const char *salt,
+ char *buf, unsigned len)
+{
+ char *res;
+ res = px_crypt_md5(psw, salt, buf, len);
+ return res;
+}
+
+static char *
+run_crypt_bf(const char *psw, const char *salt,
+ char *buf, unsigned len)
+{
+ char *res;
+
+ res = _crypt_blowfish_rn(psw, salt, buf, len);
+ if (!res)
+ return NULL;
+ strcpy(buf, res);
+ return buf;
+}
+
+static struct
+{
+ char *id;
+ unsigned id_len;
+ char *(*crypt) (const char *psw, const char *salt,
+ char *buf, unsigned len);
+} px_crypt_list[] =
+
+{
+ { "$2a$", 4, run_crypt_bf },
+ { "$2$", 3, NULL }, /* N/A */
+ { "$1$", 3, run_crypt_md5 },
+ { "_", 1, run_crypt_des },
+ { "", 0, run_crypt_des },
+ { NULL, 0, NULL }
+};
+
+char *
+px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
+{
+ int i;
+
+ for (i = 0; px_crypt_list[i].id; i++)
+ {
+ if (!px_crypt_list[i].id_len)
+ break;
+ if (!strncmp(salt, px_crypt_list[i].id, px_crypt_list[i].id_len))
+ break;
+ }
+
+ if (px_crypt_list[i].crypt == NULL)
+ return NULL;
+
+ return px_crypt_list[i].crypt(psw, salt, buf, len);
+}
+
+#else /* PX_SYSTEM_CRYPT */
+
+extern char *crypt(const char *psw, const char *salt);
+
+char *
+px_crypt(const char *psw, const char *salt,
+ char *buf, unsigned len)
+{
+ char *res;
+
+ res = crypt(psw, salt);
+ if (!res || strlen(res) >= len)
+ return NULL;
+ strcpy(buf, res);
+ return buf;
+}
+#endif
+
+/*
+ * salt generators
+ */
+
+static int my_rand64()
+{
+ return random() % 64;
+}
+
+static uint
+gen_des_salt(char *buf)
+{
+ buf[0] = px_crypt_a64[my_rand64()];
+ buf[1] = px_crypt_a64[my_rand64()];
+ buf[2] = 0;
+
+ return 2;
+}
+
+static uint
+gen_xdes_salt(char *buf)
+{
+ strcpy(buf, "_12345678");
+
+ px_crypt_to64(buf+1, (long)PX_XDES_ROUNDS, 4);
+ px_crypt_to64(buf+5, random(), 4);
+
+ return 9;
+}
+
+static uint
+gen_md5_salt(char *buf)
+{
+ int i;
+ strcpy(buf, "$1$12345678$");
+
+ for (i = 0; i < 8; i++)
+ buf[3 + i] = px_crypt_a64[my_rand64()];
+
+ return 12;
+}
+
+static uint
+gen_bf_salt(char *buf)
+{
+ int i, count;
+ char *s;
+ char saltbuf[16+3];
+ unsigned slen = 16;
+ uint32 *v;
+
+ for (i = 0; i < slen; i++)
+ saltbuf[i] = random() & 255;
+ saltbuf[16] = 0;
+ saltbuf[17] = 0;
+ saltbuf[18] = 0;
+
+ strcpy(buf, "$2a$00$0123456789012345678901");
+
+ count = PX_BF_ROUNDS;
+ buf[4] = '0' + count / 10;
+ buf[5] = '0' + count % 10;
+
+ s = buf + 7;
+ for (i = 0; i < slen; )
+ {
+ v = (uint32 *)&saltbuf[i];
+ if (i + 3 <= slen)
+ px_crypt_to64(s, *v, 4);
+ else
+ /* slen-i could be 1,2 make it 2,3 */
+ px_crypt_to64(s, *v, slen-i+1);
+ s += 4;
+ i += 3;
+ }
+
+ s = buf;
+ /*s = _crypt_gensalt_blowfish_rn(count, saltbuf, 16, buf, PX_MAX_CRYPT);*/
+
+ return s ? strlen(s) : 0;
+}
+
+struct generator {
+ char *name;
+ uint (*gen)(char *buf);
+};
+
+static struct generator gen_list [] = {
+ { "des", gen_des_salt },
+ { "md5", gen_md5_salt },
+ { "xdes", gen_xdes_salt },
+ { "bf", gen_bf_salt },
+ { NULL, NULL }
+};
+
+uint
+px_gen_salt(const char *salt_type, char *buf)
+{
+ int i;
+ struct generator *g;
+ for (i = 0; gen_list[i].name; i++) {
+ g = &gen_list[i];
+ if (!strcasecmp(g->name, salt_type))
+ return g->gen(buf);
+ }
+
+ return 0;
+}
+