mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Lots of patches coming in from me today :-)
When drawing up a very simple "text-drawing" of how the negotiation is done, I realised I had done this last part (fallback) in a very stupid way. Patch #4 fixes this, and does it in a much better way. Included is also the simple text-drawing of how the negotiation is done. //Magnus
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.40 1999/07/17 20:17:00 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.41 1999/09/27 03:12:58 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -452,8 +452,7 @@ be_recvauth(Port *port)
|
||||
* an error message into the postmaster logfile if it failed.
|
||||
*/
|
||||
|
||||
if (hba_getauthmethod(&port->raddr, port->user, port->database,
|
||||
port->auth_arg, &port->auth_method) != STATUS_OK)
|
||||
if (hba_getauthmethod(port) != STATUS_OK)
|
||||
PacketSendError(&port->pktInfo,
|
||||
"Missing or erroneous pg_hba.conf file, see postmaster log for details");
|
||||
|
||||
@@ -470,7 +469,6 @@ be_recvauth(Port *port)
|
||||
|
||||
AuthRequest areq = AUTH_REQ_OK;
|
||||
PacketDoneProc auth_handler = NULL;
|
||||
|
||||
switch (port->auth_method)
|
||||
{
|
||||
case uaReject:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* wherein you authenticate a user by seeing what IP address the system
|
||||
* says he comes from and possibly using ident).
|
||||
*
|
||||
* $Id: hba.c,v 1.47 1999/07/17 20:17:02 momjian Exp $
|
||||
* $Id: hba.c,v 1.48 1999/09/27 03:12:59 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -146,9 +146,7 @@ read_hba_entry2(FILE *file, UserAuth *userauth_p, char *auth_arg,
|
||||
|
||||
|
||||
static void
|
||||
process_hba_record(FILE *file, SockAddr *raddr, const char *user,
|
||||
const char *database, bool *matches_p, bool *error_p,
|
||||
UserAuth *userauth_p, char *auth_arg)
|
||||
process_hba_record(FILE *file, hbaPort *port, bool *matches_p, bool *error_p)
|
||||
{
|
||||
/*---------------------------------------------------------------------------
|
||||
Process the non-comment record in the config file that is next on the file.
|
||||
@@ -182,16 +180,16 @@ process_hba_record(FILE *file, SockAddr *raddr, const char *user,
|
||||
|
||||
/* Read the rest of the line. */
|
||||
|
||||
read_hba_entry2(file, userauth_p, auth_arg, error_p);
|
||||
read_hba_entry2(file, &port->auth_method, port->auth_arg, error_p);
|
||||
|
||||
/*
|
||||
* For now, disallow methods that need AF_INET sockets to work.
|
||||
*/
|
||||
|
||||
if (!*error_p &&
|
||||
(*userauth_p == uaIdent ||
|
||||
*userauth_p == uaKrb4 ||
|
||||
*userauth_p == uaKrb5))
|
||||
(port->auth_method == uaIdent ||
|
||||
port->auth_method == uaKrb4 ||
|
||||
port->auth_method == uaKrb5))
|
||||
*error_p = true;
|
||||
|
||||
if (*error_p)
|
||||
@@ -202,15 +200,33 @@ process_hba_record(FILE *file, SockAddr *raddr, const char *user,
|
||||
* sort of connection, ignore it.
|
||||
*/
|
||||
|
||||
if ((strcmp(db, database) != 0 && strcmp(db, "all") != 0 &&
|
||||
(strcmp(db, "sameuser") != 0 || strcmp(database, user) != 0)) ||
|
||||
raddr->sa.sa_family != AF_UNIX)
|
||||
if ((strcmp(db, port->database) != 0 && strcmp(db, "all") != 0 &&
|
||||
(strcmp(db, "sameuser") != 0 || strcmp(port->database, port->user) != 0)) ||
|
||||
port->raddr.sa.sa_family != AF_UNIX)
|
||||
return;
|
||||
}
|
||||
else if (strcmp(buf, "host") == 0)
|
||||
else if (strcmp(buf, "host") == 0 || strcmp(buf, "hostssl") == 0)
|
||||
{
|
||||
struct in_addr file_ip_addr,
|
||||
mask;
|
||||
bool discard = 0; /* Discard this entry */
|
||||
|
||||
#ifdef USE_SSL
|
||||
/* If SSL, then check that we are on SSL */
|
||||
if (strcmp(buf, "hostssl") == 0) {
|
||||
if (!port->ssl)
|
||||
discard = 1;
|
||||
|
||||
/* Placeholder to require specific SSL level, perhaps? */
|
||||
/* Or a client certificate */
|
||||
|
||||
/* Since we were on SSL, proceed as with normal 'host' mode */
|
||||
}
|
||||
#else
|
||||
/* If not SSL, we don't support this */
|
||||
if (strcmp(buf,"hostssl") == 0)
|
||||
goto syntax;
|
||||
#endif
|
||||
|
||||
/* Get the database. */
|
||||
|
||||
@@ -252,20 +268,27 @@ process_hba_record(FILE *file, SockAddr *raddr, const char *user,
|
||||
* info from it.
|
||||
*/
|
||||
|
||||
read_hba_entry2(file, userauth_p, auth_arg, error_p);
|
||||
read_hba_entry2(file, &port->auth_method, port->auth_arg, error_p);
|
||||
|
||||
if (*error_p)
|
||||
goto syntax;
|
||||
|
||||
/*
|
||||
* If told to discard earlier. Moved down here so we don't get
|
||||
* "out of sync" with the file.
|
||||
*/
|
||||
if (discard)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If this record isn't for our database, or this is the wrong
|
||||
* sort of connection, ignore it.
|
||||
*/
|
||||
|
||||
if ((strcmp(db, database) != 0 && strcmp(db, "all") != 0 &&
|
||||
(strcmp(db, "sameuser") != 0 || strcmp(database, user) != 0)) ||
|
||||
raddr->sa.sa_family != AF_INET ||
|
||||
((file_ip_addr.s_addr ^ raddr->in.sin_addr.s_addr) & mask.s_addr) != 0x0000)
|
||||
if ((strcmp(db, port->database) != 0 && strcmp(db, "all") != 0 &&
|
||||
(strcmp(db, "sameuser") != 0 || strcmp(port->database, port->user) != 0)) ||
|
||||
port->raddr.sa.sa_family != AF_INET ||
|
||||
((file_ip_addr.s_addr ^ port->raddr.in.sin_addr.s_addr) & mask.s_addr) != 0x0000)
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -291,9 +314,7 @@ syntax:
|
||||
|
||||
|
||||
static void
|
||||
process_open_config_file(FILE *file, SockAddr *raddr, const char *user,
|
||||
const char *database, bool *hba_ok_p,
|
||||
UserAuth *userauth_p, char *auth_arg)
|
||||
process_open_config_file(FILE *file, hbaPort *port, bool *hba_ok_p)
|
||||
{
|
||||
/*---------------------------------------------------------------------------
|
||||
This function does the same thing as find_hba_entry, only with
|
||||
@@ -316,8 +337,7 @@ process_open_config_file(FILE *file, SockAddr *raddr, const char *user,
|
||||
if (c == '#')
|
||||
read_through_eol(file);
|
||||
else
|
||||
process_hba_record(file, raddr, user, database,
|
||||
&found_entry, &error, userauth_p, auth_arg);
|
||||
process_hba_record(file, port, &found_entry, &error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,7 +346,7 @@ process_open_config_file(FILE *file, SockAddr *raddr, const char *user,
|
||||
/* If no matching entry was found, synthesize 'reject' entry. */
|
||||
|
||||
if (!found_entry)
|
||||
*userauth_p = uaReject;
|
||||
port->auth_method = uaReject;
|
||||
|
||||
*hba_ok_p = true;
|
||||
}
|
||||
@@ -335,8 +355,7 @@ process_open_config_file(FILE *file, SockAddr *raddr, const char *user,
|
||||
|
||||
|
||||
static void
|
||||
find_hba_entry(SockAddr *raddr, const char *user, const char *database,
|
||||
bool *hba_ok_p, UserAuth *userauth_p, char *auth_arg)
|
||||
find_hba_entry(hbaPort *port, bool *hba_ok_p)
|
||||
{
|
||||
/*
|
||||
* Read the config file and find an entry that allows connection from
|
||||
@@ -412,8 +431,7 @@ find_hba_entry(SockAddr *raddr, const char *user, const char *database,
|
||||
}
|
||||
else
|
||||
{
|
||||
process_open_config_file(file, raddr, user, database, hba_ok_p,
|
||||
userauth_p, auth_arg);
|
||||
process_open_config_file(file, port, hba_ok_p);
|
||||
FreeFile(file);
|
||||
}
|
||||
pfree(conf_file);
|
||||
@@ -1057,8 +1075,7 @@ GetCharSetByHost(char *TableName, int host, const char *DataDir)
|
||||
#endif
|
||||
|
||||
int
|
||||
hba_getauthmethod(SockAddr *raddr, char *user, char *database,
|
||||
char *auth_arg, UserAuth *auth_method)
|
||||
hba_getauthmethod(hbaPort *port)
|
||||
{
|
||||
/*---------------------------------------------------------------------------
|
||||
Determine what authentication method should be used when accessing database
|
||||
@@ -1070,7 +1087,7 @@ hba_getauthmethod(SockAddr *raddr, char *user, char *database,
|
||||
----------------------------------------------------------------------------*/
|
||||
bool hba_ok = false;
|
||||
|
||||
find_hba_entry(raddr, user, database, &hba_ok, auth_method, auth_arg);
|
||||
find_hba_entry(port, &hba_ok);
|
||||
|
||||
return hba_ok ? STATUS_OK : STATUS_ERROR;
|
||||
}
|
||||
|
||||
@@ -79,6 +79,18 @@
|
||||
#
|
||||
# krb5: Kerberos V5 authentication is used.
|
||||
|
||||
# Record type "hostssl"
|
||||
# ---------------------
|
||||
#
|
||||
# This record identifies the authentication to use when connecting to a
|
||||
# particular database via TCP/IP sockets over SSL. Note that normal
|
||||
# "host" records are also matched - "hostssl" records can be used to
|
||||
# require a SSL connection.
|
||||
# This keyword is only available if the server is compiled with SSL support
|
||||
# enabled.
|
||||
#
|
||||
# The format of this record is identical to that of "host".
|
||||
|
||||
# Record type "local"
|
||||
# ------------------
|
||||
#
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pqcomm.c,v 1.83 1999/09/08 22:57:12 tgl Exp $
|
||||
* $Id: pqcomm.c,v 1.84 1999/09/27 03:12:59 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -436,8 +436,16 @@ pq_recvbuf(void)
|
||||
/* Can fill buffer from PqRecvLength and upwards */
|
||||
for (;;)
|
||||
{
|
||||
int r = recv(MyProcPort->sock, PqRecvBuffer + PqRecvLength,
|
||||
PQ_BUFFER_SIZE - PqRecvLength, 0);
|
||||
int r;
|
||||
|
||||
#ifdef USE_SSL
|
||||
if (MyProcPort->ssl)
|
||||
r = SSL_read(MyProcPort->ssl, PqRecvBuffer + PqRecvLength,
|
||||
PQ_BUFFER_SIZE - PqRecvLength);
|
||||
else
|
||||
#endif
|
||||
r = recv(MyProcPort->sock, PqRecvBuffer + PqRecvLength,
|
||||
PQ_BUFFER_SIZE - PqRecvLength, 0);
|
||||
|
||||
if (r < 0)
|
||||
{
|
||||
@@ -604,7 +612,13 @@ pq_flush(void)
|
||||
|
||||
while (bufptr < bufend)
|
||||
{
|
||||
int r = send(MyProcPort->sock, bufptr, bufend - bufptr, 0);
|
||||
int r;
|
||||
#ifdef USE_SSL
|
||||
if (MyProcPort->ssl)
|
||||
r = SSL_write(MyProcPort->ssl, bufptr, bufend - bufptr);
|
||||
else
|
||||
#endif
|
||||
r = send(MyProcPort->sock, bufptr, bufend - bufptr, 0);
|
||||
|
||||
if (r <= 0)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.22 1999/07/17 20:17:03 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.23 1999/09/27 03:12:59 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -50,13 +50,20 @@ PacketReceiveSetup(Packet *pkt, PacketDoneProc iodone, void *arg)
|
||||
*/
|
||||
|
||||
int
|
||||
PacketReceiveFragment(Packet *pkt, int sock)
|
||||
PacketReceiveFragment(Port *port)
|
||||
{
|
||||
int got;
|
||||
Packet *pkt = &port->pktInfo;
|
||||
|
||||
if ((got = read(sock, pkt->ptr, pkt->nrtodo)) > 0)
|
||||
#ifdef USE_SSL
|
||||
if (port->ssl)
|
||||
got = SSL_read(port->ssl, pkt->ptr, pkt->nrtodo);
|
||||
else
|
||||
#endif
|
||||
got = read(port->sock, pkt->ptr, pkt->nrtodo);
|
||||
if (got > 0)
|
||||
{
|
||||
pkt->nrtodo -= got;
|
||||
pkt->nrtodo -= got;
|
||||
pkt->ptr += got;
|
||||
|
||||
/* See if we have got what we need for the packet length. */
|
||||
@@ -132,11 +139,19 @@ PacketSendSetup(Packet *pkt, int nbytes, PacketDoneProc iodone, void *arg)
|
||||
*/
|
||||
|
||||
int
|
||||
PacketSendFragment(Packet *pkt, int sock)
|
||||
PacketSendFragment(Port *port)
|
||||
{
|
||||
int done;
|
||||
Packet *pkt = &port->pktInfo;
|
||||
|
||||
if ((done = write(sock, pkt->ptr, pkt->nrtodo)) > 0)
|
||||
#ifdef USE_SSL
|
||||
if (port->ssl)
|
||||
done = SSL_write(port->ssl, pkt->ptr, pkt->nrtodo);
|
||||
else
|
||||
#endif
|
||||
done = write(port->sock, pkt->ptr, pkt->nrtodo);
|
||||
|
||||
if (done > 0)
|
||||
{
|
||||
pkt->nrtodo -= done;
|
||||
pkt->ptr += done;
|
||||
|
||||
Reference in New Issue
Block a user