[patch 3/6] better error handling - Mailing list pgsql-patches
From | Marko Kreen |
---|---|
Subject | [patch 3/6] better error handling |
Date | |
Msg-id | 20050319234647.126944000@grue Whole thread Raw |
In response to | [patch 0/6] pgcrypto update (Marko Kreen <marko@l-t.ee>) |
List | pgsql-patches |
* Use error codes instead of -1 * px_strerror for new error codes * calling convention change for px_gen_salt - return error code * use px_strerror in pgcrypto.c Index: pgsql/contrib/pgcrypto/px.c =================================================================== *** pgsql.orig/contrib/pgcrypto/px.c --- pgsql/contrib/pgcrypto/px.c *************** *** 33,38 **** --- 33,73 ---- #include "px.h" + struct error_desc { + int err; + const char *desc; + }; + + static const struct error_desc px_err_list[] = { + {PXE_OK, "Everything ok"}, + {PXE_ERR_GENERIC, "Some PX error (not specified)"}, + {PXE_NO_HASH, "No such hash algorithm"}, + {PXE_NO_CIPHER, "No such cipher algorithm"}, + {PXE_NOTBLOCKSIZE, "Data not a multiple of block size"}, + {PXE_BAD_OPTION, "Unknown option"}, + {PXE_BAD_FORMAT, "Badly formatted type"}, + {PXE_KEY_TOO_BIG, "Key was too big"}, + {PXE_CIPHER_INIT, "Cipher cannot be initalized ?"}, + {PXE_HASH_UNUSABLE_FOR_HMAC, "This hash algorithm is unusable for HMAC"}, + {PXE_DEV_READ_ERROR, "Error reading from random device"}, + {PXE_OSSL_RAND_ERROR, "OpenSSL PRNG error"}, + {PXE_BUG, "pgcrypto bug"}, + {PXE_ARGUMENT_ERROR, "Illegal argument to function"}, + {PXE_UNKNOWN_SALT_ALGO, "Unknown salt algorithm"}, + {PXE_BAD_SALT_ROUNDS, "Incorrect number of rounds"}, + {PXE_MCRYPT_INTERNAL, "mcrypt internal error"}, + {0, NULL}, + }; + + const char *px_strerror(int err) + { + const struct error_desc *e; + for (e = px_err_list; e->desc; e++) + if (e->err == err) + return e->desc; + return "Bad error code"; + } + const char * px_resolve_alias(const PX_Alias * list, const char *name) *************** combo_decrypt(PX_Combo * cx, const uint8 *** 215,224 **** return 0; - /* error reporting should be done in pgcrypto.c */ block_error: ! elog(WARNING, "Data not a multiple of block size"); ! return -1; } static void --- 250,257 ---- return 0; block_error: ! return PXE_NOTBLOCKSIZE; } static void *************** parse_cipher_name(char *full, char **cip *** 262,271 **** if (!strcmp(p, "pad")) *pad = p2; else ! return -1; } else ! return -1; p = q; } --- 295,304 ---- if (!strcmp(p, "pad")) *pad = p2; else ! return PXE_BAD_OPTION; } else ! return PXE_BAD_FORMAT; p = q; } *************** err1: *** 332,336 **** px_cipher_free(cx->cipher); px_free(cx); px_free(buf); ! return -1; } --- 365,369 ---- px_cipher_free(cx->cipher); px_free(cx); px_free(buf); ! return PXE_NO_CIPHER; } Index: pgsql/contrib/pgcrypto/px.h =================================================================== *** pgsql.orig/contrib/pgcrypto/px.h --- pgsql/contrib/pgcrypto/px.h *************** void px_free(void *p); *** 63,68 **** --- 63,88 ---- /* max salt returned */ #define PX_MAX_SALT_LEN 128 + /* + * PX error codes + */ + #define PXE_OK 0 + #define PXE_ERR_GENERIC -1 + #define PXE_NO_HASH -2 + #define PXE_NO_CIPHER -3 + #define PXE_NOTBLOCKSIZE -4 + #define PXE_BAD_OPTION -5 + #define PXE_BAD_FORMAT -6 + #define PXE_KEY_TOO_BIG -7 + #define PXE_CIPHER_INIT -8 + #define PXE_HASH_UNUSABLE_FOR_HMAC -9 + #define PXE_DEV_READ_ERROR -10 + #define PXE_OSSL_RAND_ERROR -11 + #define PXE_BUG -12 + #define PXE_ARGUMENT_ERROR -13 + #define PXE_UNKNOWN_SALT_ALGO -14 + #define PXE_BAD_SALT_ROUNDS -15 + #define PXE_MCRYPT_INTERNAL -16 typedef struct px_digest PX_MD; typedef struct px_alias PX_Alias; *************** int px_find_combo(const char *name, PX *** 149,154 **** --- 169,176 ---- int px_get_random_bytes(uint8 *dst, unsigned count); + const char *px_strerror(int err); + const char *px_resolve_alias(const PX_Alias * aliases, const char *name); #define px_md_result_size(md) (md)->result_size(md) Index: pgsql/contrib/pgcrypto/internal.c =================================================================== *** pgsql.orig/contrib/pgcrypto/internal.c --- pgsql/contrib/pgcrypto/internal.c *************** rj_init(PX_Cipher * c, const uint8 *key, *** 275,281 **** else if (klen <= 256 / 8) cx->keylen = 256 / 8; else ! return -1; memcpy(&cx->keybuf, key, klen); --- 275,281 ---- else if (klen <= 256 / 8) cx->keylen = 256 / 8; else ! return PXE_KEY_TOO_BIG; memcpy(&cx->keybuf, key, klen); *************** rj_encrypt(PX_Cipher * c, const uint8 *d *** 300,313 **** if (!cx->is_init) { if (rj_real_init(cx, 1)) ! return -1; } if (dlen == 0) return 0; if (dlen & 15) ! return -1; memcpy(res, data, dlen); --- 300,313 ---- if (!cx->is_init) { if (rj_real_init(cx, 1)) ! return PXE_CIPHER_INIT; } if (dlen == 0) return 0; if (dlen & 15) ! return PXE_NOTBLOCKSIZE; memcpy(res, data, dlen); *************** rj_decrypt(PX_Cipher * c, const uint8 *d *** 329,341 **** if (!cx->is_init) if (rj_real_init(cx, 0)) ! return -1; if (dlen == 0) return 0; if (dlen & 15) ! return -1; memcpy(res, data, dlen); --- 329,341 ---- if (!cx->is_init) if (rj_real_init(cx, 0)) ! return PXE_CIPHER_INIT; if (dlen == 0) return 0; if (dlen & 15) ! return PXE_NOTBLOCKSIZE; memcpy(res, data, dlen); *************** bf_encrypt(PX_Cipher * c, const uint8 *d *** 422,428 **** return 0; if (dlen & 7) ! return -1; memcpy(res, data, dlen); switch (cx->mode) --- 422,428 ---- return 0; if (dlen & 7) ! return PXE_NOTBLOCKSIZE; memcpy(res, data, dlen); switch (cx->mode) *************** bf_decrypt(PX_Cipher * c, const uint8 *d *** 446,452 **** return 0; if (dlen & 7) ! return -1; memcpy(res, data, dlen); switch (cx->mode) --- 446,452 ---- return 0; if (dlen & 7) ! return PXE_NOTBLOCKSIZE; memcpy(res, data, dlen); switch (cx->mode) *************** px_find_digest(const char *name, PX_MD * *** 556,562 **** return 0; } ! return -1; } int --- 556,562 ---- return 0; } ! return PXE_NO_HASH; } int *************** px_find_cipher(const char *name, PX_Ciph *** 575,581 **** } if (c == NULL) ! return -1; *res = c; return 0; --- 575,581 ---- } if (c == NULL) ! return PXE_NO_CIPHER; *res = c; return 0; Index: pgsql/contrib/pgcrypto/openssl.c =================================================================== *** pgsql.orig/contrib/pgcrypto/openssl.c --- pgsql/contrib/pgcrypto/openssl.c *************** px_find_digest(const char *name, PX_MD * *** 112,118 **** md = EVP_get_digestbyname(name); if (md == NULL) ! return -1; ctx = px_alloc(sizeof(*ctx)); EVP_DigestInit(ctx, md); --- 112,118 ---- md = EVP_get_digestbyname(name); if (md == NULL) ! return PXE_NO_HASH; ctx = px_alloc(sizeof(*ctx)); EVP_DigestInit(ctx, md); *************** px_find_cipher(const char *name, PX_Ciph *** 504,510 **** if (!strcmp(i->name, name)) break; if (i->name == NULL) ! return -1; od = px_alloc(sizeof(*od)); memset(od, 0, sizeof(*od)); --- 504,510 ---- if (!strcmp(i->name, name)) break; if (i->name == NULL) ! return PXE_NO_CIPHER; od = px_alloc(sizeof(*od)); memset(od, 0, sizeof(*od)); Index: pgsql/contrib/pgcrypto/px-hmac.c =================================================================== *** pgsql.orig/contrib/pgcrypto/px-hmac.c --- pgsql/contrib/pgcrypto/px-hmac.c *************** px_find_hmac(const char *name, PX_HMAC * *** 158,164 **** if (bs < 2) { px_md_free(md); ! return -1; } h = px_alloc(sizeof(*h)); --- 158,164 ---- if (bs < 2) { px_md_free(md); ! return PXE_HASH_UNUSABLE_FOR_HMAC; } h = px_alloc(sizeof(*h)); Index: pgsql/contrib/pgcrypto/random.c =================================================================== *** pgsql.orig/contrib/pgcrypto/random.c --- pgsql/contrib/pgcrypto/random.c *************** safe_read(int fd, void *buf, size_t coun *** 55,61 **** { if (errno == EINTR) continue; ! return -1; } p += res; done += res; --- 55,61 ---- { if (errno == EINTR) continue; ! return PXE_DEV_READ_ERROR; } p += res; done += res; *************** px_get_random_bytes(uint8 *dst, unsigned *** 72,78 **** fd = open(RAND_DEV, O_RDONLY); if (fd == -1) ! return -1; res = safe_read(fd, dst, count); close(fd); return res; --- 72,78 ---- fd = open(RAND_DEV, O_RDONLY); if (fd == -1) ! return PXE_DEV_READ_ERROR; res = safe_read(fd, dst, count); close(fd); return res; *************** px_get_random_bytes(uint8 *dst, unsigned *** 117,126 **** */ res = RAND_bytes(dst, count); ! if (res > 0) return count; ! return -1; } #else --- 117,126 ---- */ res = RAND_bytes(dst, count); ! if (res == 1) return count; ! return PXE_OSSL_RAND_ERROR; } #else Index: pgsql/contrib/pgcrypto/px-crypt.c =================================================================== *** pgsql.orig/contrib/pgcrypto/px-crypt.c --- pgsql/contrib/pgcrypto/px-crypt.c *************** static struct generator gen_list[] = { *** 147,185 **** {NULL, NULL, 0, 0, 0, 0} }; ! unsigned px_gen_salt(const char *salt_type, char *buf, int rounds) { ! int i, ! res; struct generator *g; char *p; char rbuf[16]; ! for (i = 0; gen_list[i].name; i++) ! { ! g = &gen_list[i]; ! if (pg_strcasecmp(g->name, salt_type) != 0) ! continue; ! ! if (g->def_rounds) ! { ! if (rounds == 0) ! rounds = g->def_rounds; ! ! if (rounds < g->min_rounds || rounds > g->max_rounds) ! return 0; ! } ! ! res = px_get_random_bytes(rbuf, g->input_len); ! if (res != g->input_len) ! return 0; ! p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN); ! memset(rbuf, 0, sizeof(rbuf)); ! return p != NULL ? strlen(p) : 0; } ! return 0; } --- 147,186 ---- {NULL, NULL, 0, 0, 0, 0} }; ! int px_gen_salt(const char *salt_type, char *buf, int rounds) { ! int res; struct generator *g; char *p; char rbuf[16]; ! for (g = gen_list; g->name; g++) ! if (pg_strcasecmp(g->name, salt_type) == 0) ! break; ! ! if (g->name == NULL) ! return PXE_UNKNOWN_SALT_ALGO; ! if (g->def_rounds) ! { ! if (rounds == 0) ! rounds = g->def_rounds; ! if (rounds < g->min_rounds || rounds > g->max_rounds) ! return PXE_BAD_SALT_ROUNDS; } ! res = px_get_random_bytes(rbuf, g->input_len); ! if (res < 0) ! return res; ! ! p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN); ! memset(rbuf, 0, sizeof(rbuf)); ! ! if (p == NULL) ! return PXE_BAD_SALT_ROUNDS; ! ! return strlen(p); } + Index: pgsql/contrib/pgcrypto/px-crypt.h =================================================================== *** pgsql.orig/contrib/pgcrypto/px-crypt.h --- pgsql/contrib/pgcrypto/px-crypt.h *************** *** 49,55 **** * main interface */ char *px_crypt(const char *psw, const char *salt, char *buf, unsigned buflen); ! unsigned px_gen_salt(const char *salt_type, char *dst, int rounds); /* * internal functions --- 49,55 ---- * main interface */ char *px_crypt(const char *psw, const char *salt, char *buf, unsigned buflen); ! int px_gen_salt(const char *salt_type, char *dst, int rounds); /* * internal functions Index: pgsql/contrib/pgcrypto/pgcrypto.c =================================================================== *** pgsql.orig/contrib/pgcrypto/pgcrypto.c --- pgsql/contrib/pgcrypto/pgcrypto.c *************** Datum *** 190,196 **** pg_gen_salt(PG_FUNCTION_ARGS) { text *arg0; ! unsigned len; text *res; char buf[PX_MAX_SALT_LEN + 1]; --- 190,196 ---- pg_gen_salt(PG_FUNCTION_ARGS) { text *arg0; ! int len; text *res; char buf[PX_MAX_SALT_LEN + 1]; *************** pg_gen_salt(PG_FUNCTION_ARGS) *** 204,213 **** memcpy(buf, VARDATA(arg0), len); buf[len] = 0; len = px_gen_salt(buf, buf, 0); ! if (len == 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ! errmsg("no such crypt algorithm"))); res = (text *) palloc(len + VARHDRSZ); VARATT_SIZEP(res) = len + VARHDRSZ; --- 204,213 ---- memcpy(buf, VARDATA(arg0), len); buf[len] = 0; len = px_gen_salt(buf, buf, 0); ! if (len < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ! errmsg("gen_salt: %s", px_strerror(len)))); res = (text *) palloc(len + VARHDRSZ); VARATT_SIZEP(res) = len + VARHDRSZ; *************** pg_gen_salt_rounds(PG_FUNCTION_ARGS) *** 226,232 **** { text *arg0; int rounds; ! unsigned len; text *res; char buf[PX_MAX_SALT_LEN + 1]; --- 226,232 ---- { text *arg0; int rounds; ! int len; text *res; char buf[PX_MAX_SALT_LEN + 1]; *************** pg_gen_salt_rounds(PG_FUNCTION_ARGS) *** 241,250 **** memcpy(buf, VARDATA(arg0), len); buf[len] = 0; len = px_gen_salt(buf, buf, rounds); ! if (len == 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ! errmsg("no such crypt algorithm or bad number of rounds"))); res = (text *) palloc(len + VARHDRSZ); VARATT_SIZEP(res) = len + VARHDRSZ; --- 241,250 ---- memcpy(buf, VARDATA(arg0), len); buf[len] = 0; len = px_gen_salt(buf, buf, rounds); ! if (len < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ! errmsg("gen_salt: %s", px_strerror(len)))); res = (text *) palloc(len + VARHDRSZ); VARATT_SIZEP(res) = len + VARHDRSZ; *************** pg_encrypt(PG_FUNCTION_ARGS) *** 360,366 **** pfree(res); ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), ! errmsg("encrypt error: %d", err))); } VARATT_SIZEP(res) = VARHDRSZ + rlen; --- 360,366 ---- pfree(res); ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), ! errmsg("encrypt error: %s", px_strerror(err)))); } VARATT_SIZEP(res) = VARHDRSZ + rlen; *************** pg_decrypt(PG_FUNCTION_ARGS) *** 406,412 **** if (err) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), ! errmsg("decrypt error: %d", err))); VARATT_SIZEP(res) = VARHDRSZ + rlen; --- 406,412 ---- if (err) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), ! errmsg("decrypt error: %s", px_strerror(err)))); VARATT_SIZEP(res) = VARHDRSZ + rlen; *************** pg_encrypt_iv(PG_FUNCTION_ARGS) *** 461,467 **** if (err) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), ! errmsg("encrypt_iv error: %d", err))); VARATT_SIZEP(res) = VARHDRSZ + rlen; --- 461,467 ---- if (err) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), ! errmsg("encrypt_iv error: %s", px_strerror(err)))); VARATT_SIZEP(res) = VARHDRSZ + rlen; *************** pg_decrypt_iv(PG_FUNCTION_ARGS) *** 517,523 **** if (err) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), ! errmsg("decrypt_iv error: %d", err))); VARATT_SIZEP(res) = VARHDRSZ + rlen; --- 517,523 ---- if (err) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), ! errmsg("decrypt_iv error: %s", px_strerror(err)))); VARATT_SIZEP(res) = VARHDRSZ + rlen; *************** find_provider(text *name, *** 568,574 **** if (err && !silent) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ! errmsg("%s type does not exist: \"%s\"", desc, buf))); pfree(buf); --- 568,574 ---- if (err && !silent) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), ! errmsg("Cannot use \"%s\": %s", buf, px_strerror(err)))); pfree(buf); --
pgsql-patches by date: