diff options
author | Bruce Momjian <bruce@momjian.us> | 2001-08-15 18:42:16 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2001-08-15 18:42:16 +0000 |
commit | 38bb1abcda9119957e836f731a1cfea6d2079499 (patch) | |
tree | 8f61d7b57cc171d8307a81dc7c4b7a382be58f43 /src/backend/libpq | |
parent | 397f65d102b7f9998411f2a8c2d1c66dfe712320 (diff) | |
download | postgresql-38bb1abcda9119957e836f731a1cfea6d2079499.tar.gz postgresql-38bb1abcda9119957e836f731a1cfea6d2079499.zip |
Use MD5 for wire protocol encryption for >= 7.2 client/server.
Allow pg_shadow to be MD5 encrypted.
Add ENCRYPTED/UNENCRYPTED option to CREATE/ALTER user.
Add password_encryption postgresql.conf option.
Update wire protocol version to 2.1.
Diffstat (limited to 'src/backend/libpq')
-rw-r--r-- | src/backend/libpq/Makefile | 4 | ||||
-rw-r--r-- | src/backend/libpq/auth.c | 18 | ||||
-rw-r--r-- | src/backend/libpq/crypt.c | 55 | ||||
-rw-r--r-- | src/backend/libpq/hba.c | 22 | ||||
-rw-r--r-- | src/backend/libpq/password.c | 15 | ||||
-rw-r--r-- | src/backend/libpq/pg_hba.conf.sample | 5 |
6 files changed, 86 insertions, 33 deletions
diff --git a/src/backend/libpq/Makefile b/src/backend/libpq/Makefile index 619a0c86900..d71e5c9765d 100644 --- a/src/backend/libpq/Makefile +++ b/src/backend/libpq/Makefile @@ -4,7 +4,7 @@ # Makefile for libpq subsystem (backend half of libpq interface) # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.24 2000/08/25 10:00:30 petere Exp $ +# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.25 2001/08/15 18:42:14 momjian Exp $ # #------------------------------------------------------------------------- @@ -15,7 +15,7 @@ include $(top_builddir)/src/Makefile.global # be-fsstubs is here for historical reasons, probably belongs elsewhere OBJS = be-fsstubs.o \ - auth.o crypt.o hba.o password.o \ + auth.o crypt.o hba.o md5.o password.o \ pqcomm.o pqformat.o pqpacket.o pqsignal.o util.o diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 81d4865ce69..fe7bc3c9d1d 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.56 2001/08/07 10:44:13 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.57 2001/08/15 18:42:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -420,9 +420,8 @@ auth_failed(Port *port) authmethod = "IDENT"; break; case uaPassword: - authmethod = "Password"; - break; case uaCrypt: + case uaMD5: authmethod = "Password"; break; } @@ -507,6 +506,11 @@ ClientAuthentication(Port *port) status = recv_and_check_password_packet(port); break; + case uaMD5: + sendAuthRequest(port, AUTH_REQ_MD5); + status = recv_and_check_password_packet(port); + break; + case uaTrust: status = STATUS_OK; break; @@ -532,7 +536,7 @@ sendAuthRequest(Port *port, AuthRequest areq) pq_sendint(&buf, (int32) areq, sizeof(int32)); /* Add the salt for encrypted passwords. */ - if (areq == AUTH_REQ_CRYPT) + if (areq == AUTH_REQ_CRYPT || areq == AUTH_REQ_MD5) { pq_sendint(&buf, port->salt[0], 1); pq_sendint(&buf, port->salt[1], 1); @@ -557,7 +561,7 @@ recv_and_check_password_packet(Port *port) if (pq_eof() == EOF || pq_getint(&len, 4) == EOF) return STATUS_ERROR; /* client didn't want to send password */ initStringInfo(&buf); - pq_getstr(&buf); + pq_getstr(&buf); /* receive password */ if (DebugLvl) fprintf(stderr, "received password packet with len=%d, pw=%s\n", @@ -579,7 +583,7 @@ checkPassword(Port *port, char *user, char *password) if (port->auth_arg[0] != '\0') return verify_password(port, user, password); - return crypt_verify(port, user, password); + return md5_crypt_verify(port, user, password); } @@ -594,7 +598,6 @@ old_be_recvauth(Port *port) MsgType msgtype = (MsgType) port->proto; /* Handle the authentication that's offered. */ - switch (msgtype) { case STARTUP_KRB4_MSG: @@ -634,6 +637,7 @@ map_old_to_new(Port *port, UserAuth old, int status) switch (port->auth_method) { case uaCrypt: + case uaMD5: case uaReject: status = STATUS_ERROR; break; diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index e89963f9f65..62393d26e02 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -9,7 +9,7 @@ * Dec 17, 1997 - Todd A. Brandys * Orignal Version Completed. * - * $Id: crypt.c,v 1.32 2001/06/23 23:26:17 petere Exp $ + * $Id: crypt.c,v 1.33 2001/08/15 18:42:14 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -19,6 +19,7 @@ #include "postgres.h" #include "libpq/crypt.h" +#include "libpq/md5.h" #include "miscadmin.h" #include "storage/fd.h" #include "utils/nabstime.h" @@ -254,7 +255,7 @@ crypt_getloginfo(const char *user, char **passwd, char **valuntil) /*-------------------------------------------------------------------------*/ int -crypt_verify(const Port *port, const char *user, const char *pgpass) +md5_crypt_verify(const Port *port, const char *user, const char *pgpass) { char *passwd, @@ -280,9 +281,47 @@ crypt_verify(const Port *port, const char *user, const char *pgpass) * Compare with the encrypted or plain password depending on the * authentication method being used for this connection. */ - - crypt_pwd = - (port->auth_method == uaCrypt ? crypt(passwd, port->salt) : passwd); + switch (port->auth_method) + { + case uaCrypt: + crypt_pwd = crypt(passwd, port->salt); + break; + case uaMD5: + crypt_pwd = palloc(MD5_PASSWD_LEN+1); + + if (isMD5(passwd)) + { + if (!EncryptMD5(passwd + strlen("md5"), + (char *)port->salt, crypt_pwd)) + { + pfree(crypt_pwd); + return STATUS_ERROR; + } + } + else + { + char *crypt_pwd2 = palloc(MD5_PASSWD_LEN+1); + + if (!EncryptMD5(passwd, port->user, crypt_pwd2)) + { + pfree(crypt_pwd); + pfree(crypt_pwd2); + return STATUS_ERROR; + } + if (!EncryptMD5(crypt_pwd2 + strlen("md5"), port->salt, + crypt_pwd)) + { + pfree(crypt_pwd); + pfree(crypt_pwd2); + return STATUS_ERROR; + } + pfree(crypt_pwd2); + } + break; + default: + crypt_pwd = passwd; + break; + } if (!strcmp(pgpass, crypt_pwd)) { @@ -302,9 +341,11 @@ crypt_verify(const Port *port, const char *user, const char *pgpass) retval = STATUS_OK; } - pfree((void *) passwd); + pfree(passwd); if (valuntil) - pfree((void *) valuntil); + pfree(valuntil); + if (port->auth_method == uaMD5) + pfree(crypt_pwd); return retval; } diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index b91427460d2..d12225ab0ea 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.61 2001/08/02 14:39:35 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.62 2001/08/15 18:42:15 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -203,8 +203,8 @@ free_lines(List **lines) * *error_p. line points to the next token of the line. */ static void -parse_hba_auth(List *line, UserAuth *userauth_p, char *auth_arg, - bool *error_p) +parse_hba_auth(List *line, ProtocolVersion proto, UserAuth *userauth_p, + char *auth_arg, bool *error_p) { char *token; @@ -227,7 +227,15 @@ parse_hba_auth(List *line, UserAuth *userauth_p, char *auth_arg, else if (strcmp(token, "reject") == 0) *userauth_p = uaReject; else if (strcmp(token, "crypt") == 0) - *userauth_p = uaCrypt; + { + /* if the client supports it, use MD5 */ + if (PG_PROTOCOL_MAJOR(proto) > 2 || + (PG_PROTOCOL_MAJOR(proto) == 2 && + PG_PROTOCOL_MINOR(proto) >= 1)) + *userauth_p = uaMD5; + else + *userauth_p = uaCrypt; + } else *error_p = true; line = lnext(line); @@ -285,7 +293,8 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p) line = lnext(line); if (!line) goto hba_syntax; - parse_hba_auth(line, &port->auth_method, port->auth_arg, error_p); + parse_hba_auth(line, port->proto, &port->auth_method, + port->auth_arg, error_p); if (*error_p) goto hba_syntax; @@ -354,7 +363,8 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p) line = lnext(line); if (!line) goto hba_syntax; - parse_hba_auth(line, &port->auth_method, port->auth_arg, error_p); + parse_hba_auth(line, port->proto, &port->auth_method, + port->auth_arg, error_p); if (*error_p) goto hba_syntax; diff --git a/src/backend/libpq/password.c b/src/backend/libpq/password.c index 2d4559a296c..e98ab6bc0af 100644 --- a/src/backend/libpq/password.c +++ b/src/backend/libpq/password.c @@ -2,7 +2,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: password.c,v 1.37 2001/06/18 16:11:30 momjian Exp $ + * $Id: password.c,v 1.38 2001/08/15 18:42:15 momjian Exp $ * */ @@ -82,11 +82,14 @@ verify_password(const Port *port, const char *user, const char *password) * the current code needs non-encrypted passwords to * encrypt with a random salt. */ - if (port->auth_method == uaCrypt - || test_pw == NULL || test_pw[0] == '\0' - || strcmp(test_pw, "+") == 0) - return crypt_verify(port, user, password); - + if (port->auth_method == uaCrypt || + port->auth_method == uaMD5 || + test_pw == NULL || + test_pw[0] == '\0' || + strcmp(test_pw, "+") == 0) + return md5_crypt_verify(port, user, password); + + /* external password file is crypt-only */ if (strcmp(crypt(password, test_pw), test_pw) == 0) { /* it matched. */ diff --git a/src/backend/libpq/pg_hba.conf.sample b/src/backend/libpq/pg_hba.conf.sample index 7dc39ee67b9..a489b78a70b 100644 --- a/src/backend/libpq/pg_hba.conf.sample +++ b/src/backend/libpq/pg_hba.conf.sample @@ -3,7 +3,6 @@ # # # This file controls: -# # o which hosts are allowed to connect # o how users are authenticated on each host # o databases accessible by each host @@ -24,7 +23,6 @@ # ============ # # There are three types of records: -# # o host # o hostssl # o local @@ -40,7 +38,6 @@ # host DBNAME IP_ADDRESS ADDRESS_MASK AUTH_TYPE [AUTH_ARGUMENT] # # DBNAME can be: -# # o the name of a PostgreSQL database # o "all" to indicate all databases # o "sameuser" to allow access only to databases with the same @@ -80,7 +77,6 @@ # allowed only if this record type appears. # # Format: -# # local DBNAME AUTH_TYPE [AUTH_ARGUMENT] # # This format is identical to the "host" record type except the IP_ADDRESS @@ -219,4 +215,3 @@ local all trust host all 127.0.0.1 255.255.255.255 trust - |