Skip to content

Commit

Permalink
Ensure we don't buffer GSSAPI-encrypted data
Browse files Browse the repository at this point in the history
This commit should probably be squashed before merging, but until we
know that it fixes the issue I'd prefer it separate.  Apologies for the
inconvenience.
  • Loading branch information
frozencemetery committed Mar 4, 2016
1 parent e5d42ac commit 82c8922
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 40 deletions.
14 changes: 14 additions & 0 deletions src/interfaces/libpq/fe-auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,20 @@ pg_GSS_continue(PGconn *conn)
if (maj_stat == GSS_S_COMPLETE)
gss_release_name(&lmin_s, &conn->gtarg_nam);

if (pg_GSS_should_crypto(conn) && conn->inEnd != conn->inStart)
{
/*
* If we've any data from the server buffered, it's encrypted and we
* need to decrypt it. Pass it back down a layer to decrypt.
*
* At this point in time, conn->inStart and conn->inCursor match.
*/
appendBinaryPQExpBuffer(&conn->gwritebuf,
conn->inBuffer + conn->inStart,
conn->inEnd - conn->inStart);
conn->inEnd = conn->inStart;
}

return STATUS_OK;
}

Expand Down
40 changes: 40 additions & 0 deletions src/interfaces/libpq/fe-gssapi-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,43 @@ pg_GSS_error(const char *mprefix, PGconn *conn,
/* Add the minor codes as well */
pg_GSS_error_int(&conn->errorMessage, mprefix, min_stat, GSS_C_MECH_CODE);
}

/*
* Only consider encryption when GSS context is complete
*/
ssize_t
pg_GSS_should_crypto(PGconn *conn)
{
OM_uint32 major, minor;
int open = 1;

if (conn->gctx == GSS_C_NO_CONTEXT)
return 0;
else if (conn->gencrypt)
return 1;

major = gss_inquire_context(&minor, conn->gctx,
NULL, NULL, NULL, NULL, NULL, NULL,
&open);
if (major == GSS_S_NO_CONTEXT)
{
/*
* In MIT krb5 < 1.14, it was not possible to call gss_inquire_context
* on an incomplete context. This was a violation of rfc2744 and has
* been corrected in https://github.com/krb5/krb5/pull/285
*/
return 0;
}
else if (GSS_ERROR(major))
{
pg_GSS_error(libpq_gettext("GSSAPI context state error"), conn,
major, minor);
return -1;
}
else if (open != 0)
{
conn->gencrypt = true;
return 1;
}
return 0;
}
1 change: 1 addition & 0 deletions src/interfaces/libpq/fe-gssapi-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@

void pg_GSS_error(const char *mprefix, PGconn *conn,
OM_uint32 maj_stat, OM_uint32 min_stat);
ssize_t pg_GSS_should_crypto(PGconn *conn);

#endif /* FE_GSSAPI_COMMON_H */
40 changes: 0 additions & 40 deletions src/interfaces/libpq/fe-secure-gssapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,46 +17,6 @@
#include "libpq-int.h"
#include "fe-gssapi-common.h"

/*
* Only consider encryption when GSS context is complete
*/
static ssize_t
pg_GSS_should_crypto(PGconn *conn)
{
OM_uint32 major, minor;
int open = 1;

if (conn->gctx == GSS_C_NO_CONTEXT)
return 0;
else if (conn->gencrypt)
return 1;

major = gss_inquire_context(&minor, conn->gctx,
NULL, NULL, NULL, NULL, NULL, NULL,
&open);
if (major == GSS_S_NO_CONTEXT)
{
/*
* In MIT krb5 < 1.14, it was not possible to call gss_inquire_context
* on an incomplete context. This was a violation of rfc2744 and has
* been corrected in https://github.com/krb5/krb5/pull/285
*/
return 0;
}
else if (GSS_ERROR(major))
{
pg_GSS_error(libpq_gettext("GSSAPI context state error"), conn,
major, minor);
return -1;
}
else if (open != 0)
{
conn->gencrypt = true;
return 1;
}
return 0;
}

ssize_t
pg_GSS_write(PGconn *conn, void *ptr, size_t len)
{
Expand Down

0 comments on commit 82c8922

Please sign in to comment.