aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2001-08-15 18:42:16 +0000
committerBruce Momjian <bruce@momjian.us>2001-08-15 18:42:16 +0000
commit38bb1abcda9119957e836f731a1cfea6d2079499 (patch)
tree8f61d7b57cc171d8307a81dc7c4b7a382be58f43 /src
parent397f65d102b7f9998411f2a8c2d1c66dfe712320 (diff)
downloadpostgresql-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')
-rw-r--r--src/backend/commands/user.c197
-rw-r--r--src/backend/libpq/Makefile4
-rw-r--r--src/backend/libpq/auth.c18
-rw-r--r--src/backend/libpq/crypt.c55
-rw-r--r--src/backend/libpq/hba.c22
-rw-r--r--src/backend/libpq/password.c15
-rw-r--r--src/backend/libpq/pg_hba.conf.sample5
-rw-r--r--src/backend/parser/gram.y20
-rw-r--r--src/backend/parser/keywords.c4
-rw-r--r--src/backend/utils/misc/guc.c9
-rw-r--r--src/backend/utils/misc/postgresql.conf.sample5
-rw-r--r--src/include/libpq/crypt.h6
-rw-r--r--src/include/libpq/hba.h6
-rw-r--r--src/include/libpq/pqcomm.h9
-rw-r--r--src/include/miscadmin.h8
-rw-r--r--src/interfaces/libpq/Makefile14
-rw-r--r--src/interfaces/libpq/fe-auth.c52
-rw-r--r--src/interfaces/libpq/fe-connect.c6
-rw-r--r--src/interfaces/libpq/fe-exec.c3
-rw-r--r--src/interfaces/libpq/libpq-int.h4
-rw-r--r--src/interfaces/odbc/connection.c25
-rw-r--r--src/interfaces/odbc/connection.h1
22 files changed, 322 insertions, 166 deletions
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 47c8dfa4313..7f62b199280 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.79 2001/07/12 18:02:59 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.80 2001/08/15 18:42:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,6 +25,7 @@
#include "catalog/indexing.h"
#include "commands/user.h"
#include "libpq/crypt.h"
+#include "libpq/md5.h"
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
@@ -34,7 +35,7 @@
static void CheckPgUserAclNotNull(void);
-
+extern bool Password_encryption;
/*---------------------------------------------------------------------
* write_password_file / update_pg_pwd
@@ -201,72 +202,80 @@ CreateUser(CreateUserStmt *stmt)
int max_id = -1;
List *item, *option;
char *password = NULL; /* PostgreSQL user password */
+ bool encrypt_password = Password_encryption; /* encrypt password? */
+ char encrypted_password[MD5_PASSWD_LEN+1];
int sysid = 0; /* PgSQL system id (valid if havesysid) */
bool createdb = false; /* Can the user create databases? */
bool createuser = false; /* Can this user create users? */
List *groupElts = NIL; /* The groups the user is a member of */
char *validUntil = NULL; /* The time the login is valid until */
- DefElem *dpassword = NULL;
- DefElem *dsysid = NULL;
- DefElem *dcreatedb = NULL;
- DefElem *dcreateuser = NULL;
- DefElem *dgroupElts = NULL;
- DefElem *dvalidUntil = NULL;
+ DefElem *dpassword = NULL;
+ DefElem *dsysid = NULL;
+ DefElem *dcreatedb = NULL;
+ DefElem *dcreateuser = NULL;
+ DefElem *dgroupElts = NULL;
+ DefElem *dvalidUntil = NULL;
/* Extract options from the statement node tree */
foreach(option, stmt->options)
{
DefElem *defel = (DefElem *) lfirst(option);
- if (strcasecmp(defel->defname, "password") == 0) {
- if (dpassword)
- elog(ERROR, "CREATE USER: conflicting options");
- dpassword = defel;
- }
- else if (strcasecmp(defel->defname, "sysid") == 0) {
- if (dsysid)
- elog(ERROR, "CREATE USER: conflicting options");
- dsysid = defel;
- }
- else if (strcasecmp(defel->defname, "createdb") == 0) {
- if (dcreatedb)
- elog(ERROR, "CREATE USER: conflicting options");
- dcreatedb = defel;
- }
- else if (strcasecmp(defel->defname, "createuser") == 0) {
- if (dcreateuser)
- elog(ERROR, "CREATE USER: conflicting options");
- dcreateuser = defel;
- }
- else if (strcasecmp(defel->defname, "groupElts") == 0) {
- if (dgroupElts)
- elog(ERROR, "CREATE USER: conflicting options");
- dgroupElts = defel;
- }
- else if (strcasecmp(defel->defname, "validUntil") == 0) {
- if (dvalidUntil)
- elog(ERROR, "CREATE USER: conflicting options");
- dvalidUntil = defel;
- }
- else
- elog(ERROR,"CREATE USER: option \"%s\" not recognized",
- defel->defname);
- }
-
- if (dcreatedb)
+ if (strcasecmp(defel->defname, "password") == 0 ||
+ strcasecmp(defel->defname, "encryptedPassword") == 0 ||
+ strcasecmp(defel->defname, "unencryptedPassword") == 0) {
+ if (dpassword)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dpassword = defel;
+ if (strcasecmp(defel->defname, "encryptedPassword") == 0)
+ encrypt_password = true;
+ else if (strcasecmp(defel->defname, "unencryptedPassword") == 0)
+ encrypt_password = false;
+ }
+ else if (strcasecmp(defel->defname, "sysid") == 0) {
+ if (dsysid)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dsysid = defel;
+ }
+ else if (strcasecmp(defel->defname, "createdb") == 0) {
+ if (dcreatedb)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dcreatedb = defel;
+ }
+ else if (strcasecmp(defel->defname, "createuser") == 0) {
+ if (dcreateuser)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dcreateuser = defel;
+ }
+ else if (strcasecmp(defel->defname, "groupElts") == 0) {
+ if (dgroupElts)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dgroupElts = defel;
+ }
+ else if (strcasecmp(defel->defname, "validUntil") == 0) {
+ if (dvalidUntil)
+ elog(ERROR, "CREATE USER: conflicting options");
+ dvalidUntil = defel;
+ }
+ else
+ elog(ERROR,"CREATE USER: option \"%s\" not recognized",
+ defel->defname);
+ }
+
+ if (dcreatedb)
createdb = intVal(dcreatedb->arg) != 0;
- if (dcreateuser)
+ if (dcreateuser)
createuser = intVal(dcreateuser->arg) != 0;
- if (dsysid)
+ if (dsysid)
{
sysid = intVal(dsysid->arg);
havesysid = true;
}
- if (dvalidUntil)
+ if (dvalidUntil)
validUntil = strVal(dvalidUntil->arg);
- if (dpassword)
+ if (dpassword)
password = strVal(dpassword->arg);
- if (dgroupElts)
+ if (dgroupElts)
groupElts = (List *) dgroupElts->arg;
/* Check some permissions first */
@@ -337,8 +346,18 @@ CreateUser(CreateUserStmt *stmt)
new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser);
if (password)
- new_record[Anum_pg_shadow_passwd - 1] =
- DirectFunctionCall1(textin, CStringGetDatum(password));
+ {
+ if (!encrypt_password || isMD5(password))
+ new_record[Anum_pg_shadow_passwd - 1] =
+ DirectFunctionCall1(textin, CStringGetDatum(password));
+ else
+ {
+ if (!EncryptMD5(password, stmt->user, encrypted_password))
+ elog(ERROR, "CREATE USER: password encryption failed");
+ new_record[Anum_pg_shadow_passwd - 1] =
+ DirectFunctionCall1(textin, CStringGetDatum(encrypted_password));
+ }
+ }
if (validUntil)
new_record[Anum_pg_shadow_valuntil - 1] =
DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil));
@@ -418,6 +437,8 @@ AlterUser(AlterUserStmt *stmt)
bool null;
List *option;
char *password = NULL; /* PostgreSQL user password */
+ bool encrypt_password = Password_encryption; /* encrypt password? */
+ char encrypted_password[MD5_PASSWD_LEN+1];
int createdb = -1; /* Can the user create databases? */
int createuser = -1; /* Can this user create users? */
char *validUntil = NULL; /* The time the login is valid until */
@@ -431,10 +452,16 @@ AlterUser(AlterUserStmt *stmt)
{
DefElem *defel = (DefElem *) lfirst(option);
- if (strcasecmp(defel->defname, "password") == 0) {
+ if (strcasecmp(defel->defname, "password") == 0 ||
+ strcasecmp(defel->defname, "encryptedPassword") == 0 ||
+ strcasecmp(defel->defname, "unencryptedPassword") == 0) {
if (dpassword)
elog(ERROR, "ALTER USER: conflicting options");
dpassword = defel;
+ if (strcasecmp(defel->defname, "encryptedPassword") == 0)
+ encrypt_password = true;
+ else if (strcasecmp(defel->defname, "unencryptedPassword") == 0)
+ encrypt_password = false;
}
else if (strcasecmp(defel->defname, "createdb") == 0) {
if (dcreatedb)
@@ -445,17 +472,17 @@ AlterUser(AlterUserStmt *stmt)
if (dcreateuser)
elog(ERROR, "ALTER USER: conflicting options");
dcreateuser = defel;
- }
+ }
else if (strcasecmp(defel->defname, "validUntil") == 0) {
if (dvalidUntil)
elog(ERROR, "ALTER USER: conflicting options");
dvalidUntil = defel;
}
- else
+ else
elog(ERROR,"ALTER USER: option \"%s\" not recognized",
defel->defname);
}
-
+
if (dcreatedb)
createdb = intVal(dcreatedb->arg);
if (dcreateuser)
@@ -464,8 +491,8 @@ AlterUser(AlterUserStmt *stmt)
validUntil = strVal(dvalidUntil->arg);
if (dpassword)
password = strVal(dpassword->arg);
-
- if (password)
+
+ if (password)
CheckPgUserAclNotNull();
/* must be superuser or just want to change your own password */
@@ -552,8 +579,16 @@ AlterUser(AlterUserStmt *stmt)
/* password */
if (password)
{
- new_record[Anum_pg_shadow_passwd - 1] =
- DirectFunctionCall1(textin, CStringGetDatum(password));
+ if (!encrypt_password || isMD5(password))
+ new_record[Anum_pg_shadow_passwd - 1] =
+ DirectFunctionCall1(textin, CStringGetDatum(password));
+ else
+ {
+ if (!EncryptMD5(password, stmt->user, encrypted_password))
+ elog(ERROR, "CREATE USER: password encryption failed");
+ new_record[Anum_pg_shadow_passwd - 1] =
+ DirectFunctionCall1(textin, CStringGetDatum(encrypted_password));
+ }
new_record_nulls[Anum_pg_shadow_passwd - 1] = ' ';
}
else
@@ -793,40 +828,40 @@ CreateGroup(CreateGroupStmt *stmt)
Datum new_record[Natts_pg_group];
char new_record_nulls[Natts_pg_group];
List *item,
- *option,
+ *option,
*newlist = NIL;
ArrayType *userarray;
- int sysid = 0;
- List *userElts = NIL;
- DefElem *dsysid = NULL;
- DefElem *duserElts = NULL;
+ int sysid = 0;
+ List *userElts = NIL;
+ DefElem *dsysid = NULL;
+ DefElem *duserElts = NULL;
foreach(option, stmt->options)
{
DefElem *defel = (DefElem *) lfirst(option);
- if (strcasecmp(defel->defname, "sysid") == 0) {
- if (dsysid)
- elog(ERROR, "CREATE GROUP: conflicting options");
- dsysid = defel;
- }
- else if (strcasecmp(defel->defname, "userElts") == 0) {
- if (duserElts)
- elog(ERROR, "CREATE GROUP: conflicting options");
- duserElts = defel;
- }
- else
- elog(ERROR,"CREATE GROUP: option \"%s\" not recognized",
- defel->defname);
- }
-
- if (dsysid)
+ if (strcasecmp(defel->defname, "sysid") == 0) {
+ if (dsysid)
+ elog(ERROR, "CREATE GROUP: conflicting options");
+ dsysid = defel;
+ }
+ else if (strcasecmp(defel->defname, "userElts") == 0) {
+ if (duserElts)
+ elog(ERROR, "CREATE GROUP: conflicting options");
+ duserElts = defel;
+ }
+ else
+ elog(ERROR,"CREATE GROUP: option \"%s\" not recognized",
+ defel->defname);
+ }
+
+ if (dsysid)
{
sysid = intVal(dsysid->arg);
havesysid = true;
}
- if (duserElts)
+ if (duserElts)
userElts = (List *) duserElts->arg;
/*
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
-
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 391d821119a..57242a5978a 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.244 2001/08/13 21:34:51 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.245 2001/08/15 18:42:15 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -306,7 +306,7 @@ static void doNegateFloat(Value *v);
CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC,
DISTINCT, DOUBLE, DROP,
- ELSE, END_TRANS, ESCAPE, EXCEPT, EXECUTE, EXISTS, EXTRACT,
+ ELSE, ENCRYPTED, END_TRANS, ESCAPE, EXCEPT, EXECUTE, EXISTS, EXTRACT,
FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
@@ -319,7 +319,7 @@ static void doNegateFloat(Value *v);
SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME, SUBSTRING,
TABLE, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR,
TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
- UNION, UNIQUE, UNKNOWN, UPDATE, USER, USING,
+ UNENCRYPTED, UNION, UNIQUE, UNKNOWN, UPDATE, USER, USING,
VALUES, VARCHAR, VARYING, VIEW,
WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
@@ -558,6 +558,18 @@ OptUserElem: PASSWORD Sconst
$$->defname = "password";
$$->arg = (Node *)makeString($2);
}
+ | ENCRYPTED PASSWORD Sconst
+ {
+ $$ = makeNode(DefElem);
+ $$->defname = "encryptedPassword";
+ $$->arg = (Node *)makeString($3);
+ }
+ | UNENCRYPTED PASSWORD Sconst
+ {
+ $$ = makeNode(DefElem);
+ $$->defname = "unencryptedPassword";
+ $$->arg = (Node *)makeString($3);
+ }
| SYSID Iconst
{
$$ = makeNode(DefElem);
@@ -5765,6 +5777,7 @@ ColLabel: ColId { $$ = $1; }
| DISTINCT { $$ = "distinct"; }
| DO { $$ = "do"; }
| ELSE { $$ = "else"; }
+ | ENCRYPTED { $$ = "encrypted"; }
| END_TRANS { $$ = "end"; }
| EXCEPT { $$ = "except"; }
| EXISTS { $$ = "exists"; }
@@ -5836,6 +5849,7 @@ ColLabel: ColId { $$ = $1; }
| TRANSACTION { $$ = "transaction"; }
| TRIM { $$ = "trim"; }
| TRUE_P { $$ = "true"; }
+ | UNENCRYPTED { $$ = "unencrypted"; }
| UNION { $$ = "union"; }
| UNIQUE { $$ = "unique"; }
| UNKNOWN { $$ = "unknown"; }
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index 014b1198503..3fb39c0821e 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.94 2001/07/16 05:06:58 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.95 2001/08/15 18:42:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -102,6 +102,7 @@ static ScanKeyword ScanKeywords[] = {
{"each", EACH},
{"else", ELSE},
{"encoding", ENCODING},
+ {"encrypted", ENCRYPTED},
{"end", END_TRANS},
{"escape", ESCAPE},
{"except", EXCEPT},
@@ -262,6 +263,7 @@ static ScanKeyword ScanKeywords[] = {
{"truncate", TRUNCATE},
{"trusted", TRUSTED},
{"type", TYPE_P},
+ {"unencrypted", UNENCRYPTED},
{"union", UNION},
{"unique", UNIQUE},
{"unknown", UNKNOWN},
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index cc666047815..b0bb99817d1 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4,7 +4,7 @@
* Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options.
*
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.45 2001/07/05 15:19:40 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.46 2001/08/15 18:42:15 momjian Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
@@ -80,6 +80,8 @@ bool SQL_inheritance = true;
bool Australian_timezones = false;
+bool Password_encryption = false;
+
#ifndef PG_KRB_SRVTAB
#define PG_KRB_SRVTAB ""
#endif
@@ -246,11 +248,12 @@ static struct config_bool
{"sql_inheritance", PGC_USERSET, &SQL_inheritance, true, NULL},
- {"australian_timezones", PGC_USERSET, &Australian_timezones,
- false, ClearDateCache},
+ {"australian_timezones", PGC_USERSET, &Australian_timezones, false, ClearDateCache},
{"fixbtree", PGC_POSTMASTER, &FixBTree, true, NULL},
+ {"password_encryption", PGC_USERSET, &Password_encryption, false, NULL},
+
{NULL, 0, NULL, false, NULL}
};
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 6b25bbca6c6..78abcd50c28 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -176,9 +176,10 @@
#
# Misc
#
-#default_transaction_isolation = 'read committed'
-#sql_inheritance = true
#australian_timezones = false
#deadlock_timeout = 1000
+#default_transaction_isolation = 'read committed'
#max_expr_depth = 10000 # min 10
+#password_encryption = false
+#sql_inheritance = true
diff --git a/src/include/libpq/crypt.h b/src/include/libpq/crypt.h
index c3f58ee1639..030921c254b 100644
--- a/src/include/libpq/crypt.h
+++ b/src/include/libpq/crypt.h
@@ -22,10 +22,6 @@ extern int pwd_cache_count;
extern char *crypt_getpwdfilename(void);
extern char *crypt_getpwdreloadfilename(void);
-#ifdef NOT_USED
-extern MsgType crypt_salt(const char *user);
-
-#endif
-extern int crypt_verify(const Port *port, const char *user, const char *pgpass);
+extern int md5_crypt_verify(const Port *port, const char *user, const char *pgpass);
#endif
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
index 0d792da3d35..11f052d3634 100644
--- a/src/include/libpq/hba.h
+++ b/src/include/libpq/hba.h
@@ -4,7 +4,7 @@
* Interface to hba.c
*
*
- * $Id: hba.h,v 1.22 2001/08/01 23:25:39 tgl Exp $
+ * $Id: hba.h,v 1.23 2001/08/15 18:42:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -35,7 +35,9 @@ typedef enum UserAuth
uaTrust,
uaIdent,
uaPassword,
- uaCrypt
+ uaCrypt,
+ uaMD5 /* This starts as uaCrypt from pg_hba.conf, but gets
+ overridden if the client supports MD5 */
} UserAuth;
typedef struct Port hbaPort;
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 0f90ecdc67d..c709553f69b 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pqcomm.h,v 1.55 2001/03/22 04:00:48 momjian Exp $
+ * $Id: pqcomm.h,v 1.56 2001/08/15 18:42:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -90,7 +90,7 @@ typedef union SockAddr
/* The earliest and latest frontend/backend protocol version supported. */
#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(0,0)
-#define PG_PROTOCOL_LATEST PG_PROTOCOL(2,0)
+#define PG_PROTOCOL_LATEST PG_PROTOCOL(2,1)
/*
* All packets sent to the postmaster start with the length. This is omitted
@@ -127,11 +127,12 @@ typedef struct StartupPacket
/* These are the authentication requests sent by the backend. */
-#define AUTH_REQ_OK 0 /* User is authenticated */
+#define AUTH_REQ_OK 0 /* User is authenticated */
#define AUTH_REQ_KRB4 1 /* Kerberos V4 */
#define AUTH_REQ_KRB5 2 /* Kerberos V5 */
#define AUTH_REQ_PASSWORD 3 /* Password */
-#define AUTH_REQ_CRYPT 4 /* Encrypted password */
+#define AUTH_REQ_CRYPT 4 /* crypt password */
+#define AUTH_REQ_MD5 5 /* md5 password */
typedef uint32 AuthRequest;
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index c3afaf89eca..89e0670911b 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: miscadmin.h,v 1.88 2001/08/05 02:06:50 tgl Exp $
+ * $Id: miscadmin.h,v 1.89 2001/08/15 18:42:15 momjian Exp $
*
* NOTES
* some of the information in this file should be moved to
@@ -171,8 +171,10 @@ extern bool enableFsync;
extern bool allowSystemTableMods;
extern int SortMem;
-/* a few postmaster startup options are exported here so the
- configuration file processor has access to them */
+/*
+ * A few postmaster startup options are exported here so the
+ * configuration file processor can access them.
+ */
extern bool NetServer;
extern bool EnableSSL;
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 91759e9786d..73507a15b34 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -4,7 +4,7 @@
#
# Copyright (c) 1994, Regents of the University of California
#
-# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.53 2001/07/15 13:45:04 petere Exp $
+# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.54 2001/08/15 18:42:15 momjian Exp $
#
#-------------------------------------------------------------------------
@@ -20,7 +20,7 @@ SO_MINOR_VERSION= 2
override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconfdir)"'
OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
- pqexpbuffer.o dllist.o pqsignal.o \
+ pqexpbuffer.o dllist.o md5.o pqsignal.o \
$(INET_ATON) $(SNPRINTF) $(STRERROR)
ifdef MULTIBYTE
@@ -33,7 +33,7 @@ endif
SHLIB_LINK += $(filter -L%, $(LDFLAGS)) $(filter -lcrypt -ldes -lkrb -lcom_err -lcrypto -lk5crypto -lkrb5 -lssl -lsocket -lnsl -lresolv -lintl, $(LIBS))
-all: all-lib
+all: md5.c md5.h all-lib
# Shared library stuff
include $(top_srcdir)/src/Makefile.shlib
@@ -49,6 +49,12 @@ backend_src = $(top_srcdir)/src/backend
dllist.c: $(backend_src)/lib/dllist.c
rm -f $@ && $(LN_S) $< .
+md5.c: $(backend_src)/libpq/md5.c
+ rm -f $@ && $(LN_S) $< .
+
+md5.h: $(backend_src)/../include/libpq/md5.h
+ rm -f $@ && $(LN_S) $< .
+
# this only gets done if configure finds system doesn't have inet_aton()
inet_aton.c: $(backend_src)/port/inet_aton.c
rm -f $@ && $(LN_S) $< .
@@ -82,7 +88,7 @@ uninstall: uninstall-lib
rm -f $(addprefix $(DESTDIR)$(includedir)/, libpq-fe.h libpq-int.h pqexpbuffer.h)
clean distclean maintainer-clean: clean-lib
- rm -f $(OBJS) dllist.c wchar.c
+ rm -f $(OBJS) dllist.c md5.c md5.h wchar.c
rm -f $(OBJS) inet_aton.c snprintf.c strerror.c
depend dep:
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index d8b27c37729..6f874c485bb 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -10,7 +10,7 @@
* exceed INITIAL_EXPBUFFER_SIZE (currently 256 bytes).
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.48 2001/07/15 13:45:04 petere Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.49 2001/08/15 18:42:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,6 +33,7 @@
#include "libpq-fe.h"
#include "libpq-int.h"
#include "fe-auth.h"
+#include "md5.h"
#ifdef WIN32
#include "win32.h"
@@ -434,12 +435,52 @@ pg_krb5_sendauth(char *PQerrormsg, int sock,
static int
pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
{
+ int ret;
+ char *crypt_pwd;
+
/* Encrypt the password if needed. */
- if (areq == AUTH_REQ_CRYPT)
- password = crypt(password, conn->salt);
+ switch (areq)
+ {
+ case AUTH_REQ_CRYPT:
+ crypt_pwd = crypt(password, conn->salt);
+ break;
+ case AUTH_REQ_MD5:
+ {
+ char *crypt_pwd2;
+
+ if (!(crypt_pwd = malloc(MD5_PASSWD_LEN+1)) ||
+ !(crypt_pwd2 = malloc(MD5_PASSWD_LEN+1)))
+ {
+ perror("malloc");
+ return STATUS_ERROR;
+ }
+ if (!EncryptMD5(password, conn->pguser, crypt_pwd2))
+ {
+ free(crypt_pwd);
+ free(crypt_pwd2);
+ return STATUS_ERROR;
+ }
+ if (!EncryptMD5(crypt_pwd2 + strlen("md5"), conn->salt,
+ crypt_pwd))
+ {
+ free(crypt_pwd);
+ free(crypt_pwd2);
+ return STATUS_ERROR;
+ }
+ free(crypt_pwd2);
+ break;
+ }
+ default:
+ /* discard const so we can assign it */
+ crypt_pwd = (char *)password;
+ break;
+ }
- return pqPacketSend(conn, password, strlen(password) + 1);
+ ret = pqPacketSend(conn, crypt_pwd, strlen(crypt_pwd) + 1);
+ if (areq == AUTH_REQ_MD5)
+ free(crypt_pwd);
+ return ret;
}
/*
@@ -494,6 +535,7 @@ fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
case AUTH_REQ_PASSWORD:
case AUTH_REQ_CRYPT:
+ case AUTH_REQ_MD5:
if (password == NULL || *password == '\0')
{
(void) sprintf(PQerrormsg,
@@ -506,9 +548,7 @@ fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
"fe_sendauth: error sending password authentication\n");
return STATUS_ERROR;
}
-
break;
-
default:
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
libpq_gettext("authentication method %u not supported\n"), areq);
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 47f5d55c323..32983c53ad1 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.172 2001/08/03 22:11:39 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.173 2001/08/15 18:42:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1341,7 +1341,7 @@ keep_going: /* We will come back to here until there
}
/* Get the password salt if there is one. */
- if (areq == AUTH_REQ_CRYPT)
+ if (areq == AUTH_REQ_CRYPT || areq == AUTH_REQ_MD5)
{
if (pqGetnchar(conn->salt, sizeof(conn->salt), conn))
{
@@ -1960,7 +1960,7 @@ static void
closePGconn(PGconn *conn)
{
/* Note that the protocol doesn't allow us to send Terminate
- messages during the startup phase. */
+ messages during the startup phase. */
if (conn->sock >= 0 && conn->status == CONNECTION_OK)
{
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index c512f6928c6..c5dfcd4210d 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.105 2001/08/03 22:11:39 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.106 2001/08/15 18:42:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1269,7 +1269,6 @@ errout:
static int
getNotice(PGconn *conn)
{
-
/*
* Since the Notice might be pretty long, we create a temporary
* PQExpBuffer rather than using conn->workBuffer. workBuffer is
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 5e90e492f12..a681e72beed 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-int.h,v 1.36 2001/07/15 13:45:04 petere Exp $
+ * $Id: libpq-int.h,v 1.37 2001/08/15 18:42:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -45,7 +45,7 @@
* pqcomm.h describe what the backend knows, not what libpq knows.
*/
-#define PG_PROTOCOL_LIBPQ PG_PROTOCOL(2,0)
+#define PG_PROTOCOL_LIBPQ PG_PROTOCOL(2,1)
/*
* POSTGRES backend dependent Constants.
diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c
index 90fc132b981..42196df9eed 100644
--- a/src/interfaces/odbc/connection.c
+++ b/src/interfaces/odbc/connection.c
@@ -677,7 +677,7 @@ CC_connect(ConnectionClass *self, char do_password)
mylog("auth got 'R'\n");
areq = SOCK_get_int(sock, 4);
- if (areq == AUTH_REQ_CRYPT)
+ if (areq == AUTH_REQ_CRYPT || areq == AUTH_REQ_MD5)
SOCK_get_n_char(sock, salt, 2);
mylog("areq = %d\n", areq);
@@ -717,6 +717,7 @@ CC_connect(ConnectionClass *self, char do_password)
break;
case AUTH_REQ_CRYPT:
+ case AUTH_REQ_MD5:
self->errormsg = "Password crypt authentication not supported";
self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED;
return 0;
@@ -1672,15 +1673,15 @@ CC_log_error(char *func, char *desc, ConnectionClass *self)
int CC_get_max_query_len(const ConnectionClass *conn)
{
- int value;
- /* Long Queries in 7.0+ */
- if (PG_VERSION_GE(conn, 7.0))
- value = 0 /* MAX_STATEMENT_LEN */;
- /* Prior to 7.0 we used 2*BLCKSZ */
- else if (PG_VERSION_GE(conn, 6.5))
- value = (2 * BLCKSZ);
- else
- /* Prior to 6.5 we used BLCKSZ */
- value = BLCKSZ;
- return value;
+ int value;
+ /* Long Queries in 7.0+ */
+ if (PG_VERSION_GE(conn, 7.0))
+ value = 0 /* MAX_STATEMENT_LEN */;
+ /* Prior to 7.0 we used 2*BLCKSZ */
+ else if (PG_VERSION_GE(conn, 6.5))
+ value = (2 * BLCKSZ);
+ else
+ /* Prior to 6.5 we used BLCKSZ */
+ value = BLCKSZ;
+ return value;
}
diff --git a/src/interfaces/odbc/connection.h b/src/interfaces/odbc/connection.h
index d3eb8700b28..1038bf117ba 100644
--- a/src/interfaces/odbc/connection.h
+++ b/src/interfaces/odbc/connection.h
@@ -93,6 +93,7 @@ typedef enum
#define AUTH_REQ_KRB5 2
#define AUTH_REQ_PASSWORD 3
#define AUTH_REQ_CRYPT 4
+#define AUTH_REQ_MD5 5
/* Startup Packet sizes */
#define SM_DATABASE 64