Merlin Moncure wrote:
On Tue, Apr 15, 2008 at 10:48 AM,  <[EMAIL PROTECTED]> wrote:
 On Tue, Apr 15, 2008 at 09:48:37AM -0400, Merlin Moncure wrote:
 > On Tue, Apr 15, 2008 at 9:36 AM, Alvaro Herrera
 > <[EMAIL PROTECTED]> wrote:

 > >  I expect you intend to get at least the hooks in, right?
 >
 > not likely.  Keep in mind, this is not how we really wanted to do
 > things in the first place.  We don't think this is the right strategy
 > for integrating libpqtypes with libpq.  It over-complicates things and
 > we don't really see a use case outside of libpqtypes.  If a reasonable
 > case can be made for putting the hooks in, we will consider it.  Can
 > you think of any good reasons for hooking libpq outside of our
 > intentions?

 Yes, this one comes to mind:

  From: sanjay sharma
  Subject: Submission of Feature Request : RFC- for Implementing
           Transparent Data Encryption in Postgres
  <http://archives.postgresql.org/pgsql-hackers/2008-03/msg01231.php>

 I know that the original poster wanted to encrypt and decrypt things
 server-side, but as was noted in the thread this doesn't make that much
 sense because the decryption keys must be somehow kept around there.

 But for doing it transparently client-side such libpq hooks might come
 in handy...

libpqtypes was designed to handle this with our without hooking. (the
'hooking' debate was mainly about exactly how libpq and libpqtypes was
going to be separated).

libpqtypes had a superclassing concept (not much discussed on the
lists) where you could introduce new type handlers that wrapped
existing ones and was desgined exactly for things like this.  keep an
eye on our upcoming pgfoundry project.

merlin



libpqtypes should be up on pgfoundry shortly.

/* register a new type named secure_text.  Make it a
 * sub-class of bytea.  Subclass means you can extend
 * the behavior of another type.
 */
PQregisterTypeHandler(conn, "secure_text=bytea",
  put_secure_text, get_secure_text);

int put_secure_text(PGtypeArgs *args)
{
  char secure_buf[1024];
  char *text = va_arg(args->ap, char *);
  size_t len = encrypt(secure_buf, text, strlen(text));

  // tell bytea super class to put resulting bytea value
  return args->super(args, len, secure_buf);
}

int get_secure_text(PGtypeArgs *args)
{
  size_t len;
  char *secure_text;
  size_t user_buflen = va_arg(args->ap, size_t);
  char *user_buf = va_arg(args->ap, char *);

  // ask the super class, bytea, to get the bytea value
  if(args->super(args, &len, &secure_text) == -1)
    return -1;

  decrypt(user_buf, user_buflen, secure_text, len);
  return 0;
}

/* put a secure_text into a pgparam, which will encrypt it
 * and send it to the server as a bytea.  The "*" is a
 * pointer flag telling pqtypes to not make an internal copy
 * of the string (keep a direct pointer).
 */
PQputf(param, "%secure_text*", "encrypt me");

/* put it in the db, the last argument is resultFormat */
PQparamExec(conn, param, "INSERT INTO t VALUES ($1)", 1);

/* get a secure_text from a result, which will decrypt
 * the bytea field and return text to user.
 */
char text[1024];
PQgetf(res, tup_num, "%secure_text", field_num,
  sizeof(text), text);

You could make the variable arguments for %secure_text include an encryption key if you want.

--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to