00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "postgres.h"
00033
00034 #include "px.h"
00035 #include "px-crypt.h"
00036
00037
00038 static char *
00039 run_crypt_des(const char *psw, const char *salt,
00040 char *buf, unsigned len)
00041 {
00042 char *res;
00043
00044 res = px_crypt_des(psw, salt);
00045 if (strlen(res) > len - 1)
00046 return NULL;
00047 strcpy(buf, res);
00048 return buf;
00049 }
00050
00051 static char *
00052 run_crypt_md5(const char *psw, const char *salt,
00053 char *buf, unsigned len)
00054 {
00055 char *res;
00056
00057 res = px_crypt_md5(psw, salt, buf, len);
00058 return res;
00059 }
00060
00061 static char *
00062 run_crypt_bf(const char *psw, const char *salt,
00063 char *buf, unsigned len)
00064 {
00065 char *res;
00066
00067 res = _crypt_blowfish_rn(psw, salt, buf, len);
00068 return res;
00069 }
00070
00071 struct px_crypt_algo
00072 {
00073 char *id;
00074 unsigned id_len;
00075 char *(*crypt) (const char *psw, const char *salt,
00076 char *buf, unsigned len);
00077 };
00078
00079 static const struct px_crypt_algo
00080 px_crypt_list[] = {
00081 {"$2a$", 4, run_crypt_bf},
00082 {"$2x$", 4, run_crypt_bf},
00083 {"$2$", 3, NULL},
00084 {"$1$", 3, run_crypt_md5},
00085 {"_", 1, run_crypt_des},
00086 {"", 0, run_crypt_des},
00087 {NULL, 0, NULL}
00088 };
00089
00090 char *
00091 px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
00092 {
00093 const struct px_crypt_algo *c;
00094
00095 for (c = px_crypt_list; c->id; c++)
00096 {
00097 if (!c->id_len)
00098 break;
00099 if (strncmp(salt, c->id, c->id_len) == 0)
00100 break;
00101 }
00102
00103 if (c->crypt == NULL)
00104 return NULL;
00105
00106 return c->crypt(psw, salt, buf, len);
00107 }
00108
00109
00110
00111
00112
00113 struct generator
00114 {
00115 char *name;
00116 char *(*gen) (unsigned long count, const char *input, int size,
00117 char *output, int output_size);
00118 int input_len;
00119 int def_rounds;
00120 int min_rounds;
00121 int max_rounds;
00122 };
00123
00124 static struct generator gen_list[] = {
00125 {"des", _crypt_gensalt_traditional_rn, 2, 0, 0, 0},
00126 {"md5", _crypt_gensalt_md5_rn, 6, 0, 0, 0},
00127 {"xdes", _crypt_gensalt_extended_rn, 3, PX_XDES_ROUNDS, 1, 0xFFFFFF},
00128 {"bf", _crypt_gensalt_blowfish_rn, 16, PX_BF_ROUNDS, 4, 31},
00129 {NULL, NULL, 0, 0, 0, 0}
00130 };
00131
00132 int
00133 px_gen_salt(const char *salt_type, char *buf, int rounds)
00134 {
00135 int res;
00136 struct generator *g;
00137 char *p;
00138 char rbuf[16];
00139
00140 for (g = gen_list; g->name; g++)
00141 if (pg_strcasecmp(g->name, salt_type) == 0)
00142 break;
00143
00144 if (g->name == NULL)
00145 return PXE_UNKNOWN_SALT_ALGO;
00146
00147 if (g->def_rounds)
00148 {
00149 if (rounds == 0)
00150 rounds = g->def_rounds;
00151
00152 if (rounds < g->min_rounds || rounds > g->max_rounds)
00153 return PXE_BAD_SALT_ROUNDS;
00154 }
00155
00156 res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len);
00157 if (res < 0)
00158 return res;
00159
00160 p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
00161 memset(rbuf, 0, sizeof(rbuf));
00162
00163 if (p == NULL)
00164 return PXE_BAD_SALT_ROUNDS;
00165
00166 return strlen(p);
00167 }