X-Git-Url: https://git.sommitrealweird.co.uk/onak.git/blobdiff_plain/42dbc6b5efa87e868116549c5932ab62cf716568..08de0b57479d159b443adfee3e0e3b5bfcc4bbd1:/keydb_pg.c diff --git a/keydb_pg.c b/keydb_pg.c index 76129fa..8b89b71 100644 --- a/keydb_pg.c +++ b/keydb_pg.c @@ -4,6 +4,8 @@ * Jonathan McDowell * * Copyright 2002 Project Purple + * + * $Id: keydb_pg.c,v 1.14 2004/03/23 12:33:47 noodles Exp $ */ #include @@ -23,8 +25,9 @@ #include "hash.h" #include "keydb.h" #include "keyid.h" -#include "keyindex.h" +#include "decodekey.h" #include "keystructs.h" +#include "log.h" #include "mem.h" #include "onak-conf.h" #include "parsekey.h" @@ -57,7 +60,7 @@ static int keydb_putchar(void *fd, size_t count, unsigned char *c) * this file are called in order to allow the DB to be initialized ready * for access. */ -void initdb(void) +void initdb(bool readonly) { dbconn = PQsetdbLogin(config.pg_dbhost, // host NULL, // port @@ -68,8 +71,8 @@ void initdb(void) config.pg_dbpass); // password if (PQstatus(dbconn) == CONNECTION_BAD) { - fprintf(stderr, "Connection to database failed.\n"); - fprintf(stderr, "%s\n", PQerrorMessage(dbconn)); + logthing(LOGTHING_CRITICAL, "Connection to database failed."); + logthing(LOGTHING_CRITICAL, "%s", PQerrorMessage(dbconn)); PQfinish(dbconn); dbconn = NULL; exit(1); @@ -132,7 +135,8 @@ void endtrans(void) * in and then parse_keys() to parse the packets into a publickey * structure. */ -int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, bool intrans) +int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, + bool intrans) { struct openpgp_packet_list *packets = NULL; PGresult *result = NULL; @@ -168,16 +172,19 @@ int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, bool intrans fd = lo_open(dbconn, key_oid, INV_READ); if (fd < 0) { - fprintf(stderr, "Can't open large object.\n"); + logthing(LOGTHING_ERROR, + "Can't open large object."); } else { read_openpgp_stream(keydb_fetchchar, &fd, - &packets); + &packets, 0); parse_keys(packets, publickey); lo_close(dbconn, fd); + free_packet_list(packets); + packets = NULL; } } } else if (PQresultStatus(result) != PGRES_TUPLES_OK) { - fprintf(stderr, "Problem retrieving key from DB.\n"); + logthing(LOGTHING_ERROR, "Problem retrieving key from DB."); } PQclear(result); @@ -232,16 +239,19 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey) fd = lo_open(dbconn, key_oid, INV_READ); if (fd < 0) { - fprintf(stderr, "Can't open large object.\n"); + logthing(LOGTHING_ERROR, + "Can't open large object."); } else { read_openpgp_stream(keydb_fetchchar, &fd, &packets); parse_keys(packets, publickey); lo_close(dbconn, fd); + free_packet_list(packets); + packets = NULL; } } } else if (PQresultStatus(result) != PGRES_TUPLES_OK) { - fprintf(stderr, "Problem retrieving key from DB.\n"); + logthing(LOGTHING_ERROR, "Problem retrieving key from DB."); } PQclear(result); @@ -302,12 +312,14 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) key_oid = lo_creat(dbconn, INV_READ | INV_WRITE); if (key_oid == 0) { - fprintf(stderr, "Can't create key OID\n"); + logthing(LOGTHING_ERROR, "Can't create key OID"); } else { fd = lo_open(dbconn, key_oid, INV_WRITE); write_openpgp_stream(keydb_putchar, &fd, packets); lo_close(dbconn, fd); } + free_packet_list(packets); + packets = NULL; snprintf(statement, 1023, "INSERT INTO onak_keys (keyid, keydata) VALUES " @@ -317,8 +329,8 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) result = PQexec(dbconn, statement); if (PQresultStatus(result) != PGRES_COMMAND_OK) { - fprintf(stderr, "Problem storing key in DB.\n"); - fprintf(stderr, "%s\n", PQresultErrorMessage(result)); + logthing(LOGTHING_ERROR, "Problem storing key in DB."); + logthing(LOGTHING_ERROR, "%s", PQresultErrorMessage(result)); } PQclear(result); @@ -349,8 +361,9 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) } if (PQresultStatus(result) != PGRES_COMMAND_OK) { - fprintf(stderr, "Problem storing key in DB.\n"); - fprintf(stderr, "%s\n", + logthing(LOGTHING_ERROR, + "Problem storing key in DB."); + logthing(LOGTHING_ERROR, "%s", PQresultErrorMessage(result)); } /* @@ -438,7 +451,8 @@ int delete_key(uint64_t keyid, bool intrans) keyid); result = PQexec(dbconn, statement); } else if (PQresultStatus(result) != PGRES_TUPLES_OK) { - fprintf(stderr, "Problem retrieving key (%llX) from DB.\n", + logthing(LOGTHING_ERROR, + "Problem retrieving key (%llX) from DB.", keyid); } @@ -477,7 +491,8 @@ char *keyid2uid(uint64_t keyid) PQntuples(result) >= 1) { uid = strdup(PQgetvalue(result, 0, 0)); } else if (PQresultStatus(result) != PGRES_TUPLES_OK) { - fprintf(stderr, "Problem retrieving key (%llX) from DB.\n", + logthing(LOGTHING_ERROR, + "Problem retrieving key (%llX) from DB.", keyid); } @@ -489,19 +504,21 @@ char *keyid2uid(uint64_t keyid) /** * getkeysigs - Gets a linked list of the signatures on a key. * @keyid: The keyid to get the sigs for. + * @revoked: If the key is revoked. * * This function gets the list of signatures on a key. Used for key * indexing and doing stats bits. */ -struct ll *getkeysigs(uint64_t keyid) +struct ll *getkeysigs(uint64_t keyid, bool *revoked) { struct ll *sigs = NULL; PGresult *result = NULL; uint64_t signer; char statement[1024]; - int i = 0; + int i, j; int numsigs = 0; bool intrans = false; + char *str; if (!intrans) { result = PQexec(dbconn, "BEGIN"); @@ -509,18 +526,29 @@ struct ll *getkeysigs(uint64_t keyid) } snprintf(statement, 1023, - "SELECT signer FROM onak_sigs WHERE signee = '%llX'", + "SELECT DISTINCT signer FROM onak_sigs WHERE signee = '%llX'", keyid); result = PQexec(dbconn, statement); if (PQresultStatus(result) == PGRES_TUPLES_OK) { numsigs = PQntuples(result); for (i = 0; i < numsigs; i++) { - signer = strtol(PQgetvalue(result, i, 0), NULL, 16); + j = 0; + signer = 0; + str = PQgetvalue(result, i, 0); + while (str[j] != 0) { + signer <<= 4; + if (str[j] >= '0' && str[j] <= '9') { + signer += str[j] - '0'; + } else { + signer += str[j] - 'A' + 10; + } + j++; + } sigs = lladd(sigs, createandaddtohash(signer)); } } else if (PQresultStatus(result) != PGRES_TUPLES_OK) { - fprintf(stderr, "Problem retrieving key from DB.\n"); + logthing(LOGTHING_ERROR, "Problem retrieving key from DB."); } PQclear(result); @@ -529,9 +557,34 @@ struct ll *getkeysigs(uint64_t keyid) result = PQexec(dbconn, "COMMIT"); PQclear(result); } + + /* + * TODO: What do we do about revocations? We don't have the details + * stored in a separate table, so we'd have to grab the key and decode + * it, which we're trying to avoid by having a signers table. + */ + if (revoked != NULL) { + *revoked = false; + } + return sigs; } +/** + * dumpdb - dump the key database + * @filenamebase: The base filename to use for the dump. + * + * Dumps the database into one or more files, which contain pure OpenPGP + * that can be reimported into onak or gpg. filenamebase provides a base + * file name for the dump; several files may be created, all of which will + * begin with this string and then have a unique number and a .pgp + * extension. + * */ +int dumpdb(char *filenamebase) +{ + return 0; +} + /* * Include the basic keydb routines. */