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.
This commit is contained in:
Bruce Momjian 2001-08-15 18:42:16 +00:00
parent 397f65d102
commit 38bb1abcda
27 changed files with 353 additions and 188 deletions

View File

@ -1,4 +1,4 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v 1.15 2001/08/01 23:25:39 tgl Exp $ --> <!-- $Header: /cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v 1.16 2001/08/15 18:42:14 momjian Exp $ -->
<chapter id="client-authentication"> <chapter id="client-authentication">
<title>Client Authentication</title> <title>Client Authentication</title>
@ -205,11 +205,10 @@ hostssl <replaceable>database</replaceable> <replaceable>IP-address</replaceable
<para> <para>
Like the <literal>password</literal> method, but the password Like the <literal>password</literal> method, but the password
is sent over the wire encrypted using a simple is sent over the wire encrypted using a simple
challenge-response protocol. This is still not challenge-response protocol. This protects against incidental
cryptographically secure but it protects against incidental
wire-sniffing. The name of a file may follow the wire-sniffing. The name of a file may follow the
<literal>crypt</literal> keyword that contains a list of users <literal>crypt</literal> keyword. It contains a list of users
that this record pertains to. for this record.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -1,4 +1,4 @@
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.18 2001/06/22 23:27:48 petere Exp $ --> <!-- $Header: /cvsroot/pgsql/doc/src/sgml/protocol.sgml,v 1.19 2001/08/15 18:42:14 momjian Exp $ -->
<chapter id="protocol"> <chapter id="protocol">
<title>Frontend/Backend Protocol</title> <title>Frontend/Backend Protocol</title>
@ -1295,7 +1295,7 @@ EncryptedPasswordPacket (F)
</Term> </Term>
<ListItem> <ListItem>
<Para> <Para>
The encrypted (using crypt()) password. The encrypted (using MD5 or crypt()) password.
</Para> </Para>
</ListItem> </ListItem>
</VarListEntry> </VarListEntry>

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.14 2001/07/10 22:09:27 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/alter_user.sgml,v 1.15 2001/08/15 18:42:14 momjian Exp $
Postgres documentation Postgres documentation
--> -->
@ -27,7 +27,7 @@ ALTER USER <replaceable class="PARAMETER">username</replaceable> [ [ WITH ] <rep
where <replaceable class="PARAMETER">option</replaceable> can be: where <replaceable class="PARAMETER">option</replaceable> can be:
PASSWORD '<replaceable class="PARAMETER">password</replaceable>' [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
| CREATEDB | NOCREATEDB | CREATEDB | NOCREATEDB
| CREATEUSER | NOCREATEUSER | CREATEUSER | NOCREATEUSER
| VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>' | VALID UNTIL '<replaceable class="PARAMETER">abstime</replaceable>'
@ -53,10 +53,13 @@ where <replaceable class="PARAMETER">option</replaceable> can be:
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="PARAMETER">password</replaceable></term> <term><replaceable class="PARAMETER">[ encrypted | unencrypted ] password</replaceable></term>
<listitem> <listitem>
<para> <para>
The new password to be used for this account. The new password to be used for this account.
<literal>Encrypted</literal>/ <literal>unencrypted</literal>
controls whether the password is stored encrypted in the
database.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_user.sgml,v 1.17 2001/07/10 22:09:27 tgl Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/create_user.sgml,v 1.18 2001/08/15 18:42:14 momjian Exp $
Postgres documentation Postgres documentation
--> -->
@ -28,7 +28,7 @@ CREATE USER <replaceable class="PARAMETER">username</replaceable> [ [ WITH ] <re
where <replaceable class="PARAMETER">option</replaceable> can be: where <replaceable class="PARAMETER">option</replaceable> can be:
SYSID <replaceable class="PARAMETER">uid</replaceable> SYSID <replaceable class="PARAMETER">uid</replaceable>
| PASSWORD '<replaceable class="PARAMETER">password</replaceable>' | [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
| CREATEDB | NOCREATEDB | CREATEDB | NOCREATEDB
| CREATEUSER | NOCREATEUSER | CREATEUSER | NOCREATEUSER
| IN GROUP <replaceable class="PARAMETER">groupname</replaceable> [, ...] | IN GROUP <replaceable class="PARAMETER">groupname</replaceable> [, ...]
@ -72,12 +72,19 @@ where <replaceable class="PARAMETER">option</replaceable> can be:
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><replaceable class="parameter">password</replaceable></term> <term><replaceable class="parameter">[ encrypted | unencrypted ] password</replaceable></term>
<listitem> <listitem>
<para> <para>
Sets the user's password. If you do not plan to use password Sets the user's password. If you do not plan to use password
authentication you can omit this option, otherwise the user authentication you can omit this option, otherwise the user
won't be able to connect to a password-authenticated server. won't be able to connect to a password-authenticated server.
</para>
<para>
<literal>ENCRYPTED/UNENCRYPTED</literal> controls whether the
password is stored encrypted in the database. Older clients may
have trouble communicating using encrypted password storage.
</para>
<para>
See the chapter on client authentication in the See the chapter on client authentication in the
<citetitle>Administrator's Guide</citetitle> for details on <citetitle>Administrator's Guide</citetitle> for details on
how to set up authentication mechanisms. how to set up authentication mechanisms.

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.74 2001/08/09 16:20:43 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.75 2001/08/15 18:42:14 momjian Exp $
--> -->
<Chapter Id="runtime"> <Chapter Id="runtime">
@ -967,6 +967,18 @@ env PGOPTIONS='-c geqo=off' psql
<para> <para>
<variablelist> <variablelist>
<varlistentry>
<term>AUSTRALIAN_TIMEZONES (<type>bool</type>)</term>
<listitem>
<para>
If set to true, <literal>CST</literal>, <literal>EST</literal>,
and <literal>SAT</literal> are interpreted as Australian
timezones rather than as North American Central/Eastern
Timezones and Saturday. The default is false.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<indexterm> <indexterm>
<primary>deadlock</primary> <primary>deadlock</primary>
@ -1260,18 +1272,6 @@ dynamic_library_path = '/usr/local/lib:/home/my_project/lib:$libdir:$libdir/cont
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>AUSTRALIAN_TIMEZONES (<type>bool</type>)</term>
<listitem>
<para>
If set to true, <literal>CST</literal>, <literal>EST</literal>,
and <literal>SAT</literal> are interpreted as Australian
timezones rather than as North American Central/Eastern
Timezones and Saturday. The default is false.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<indexterm> <indexterm>
<primary>SSL</primary> <primary>SSL</primary>

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 "catalog/indexing.h"
#include "commands/user.h" #include "commands/user.h"
#include "libpq/crypt.h" #include "libpq/crypt.h"
#include "libpq/md5.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "utils/array.h" #include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
@ -34,7 +35,7 @@
static void CheckPgUserAclNotNull(void); static void CheckPgUserAclNotNull(void);
extern bool Password_encryption;
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
* write_password_file / update_pg_pwd * write_password_file / update_pg_pwd
@ -201,72 +202,80 @@ CreateUser(CreateUserStmt *stmt)
int max_id = -1; int max_id = -1;
List *item, *option; List *item, *option;
char *password = NULL; /* PostgreSQL user password */ 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) */ int sysid = 0; /* PgSQL system id (valid if havesysid) */
bool createdb = false; /* Can the user create databases? */ bool createdb = false; /* Can the user create databases? */
bool createuser = false; /* Can this user create users? */ bool createuser = false; /* Can this user create users? */
List *groupElts = NIL; /* The groups the user is a member of */ List *groupElts = NIL; /* The groups the user is a member of */
char *validUntil = NULL; /* The time the login is valid until */ char *validUntil = NULL; /* The time the login is valid until */
DefElem *dpassword = NULL; DefElem *dpassword = NULL;
DefElem *dsysid = NULL; DefElem *dsysid = NULL;
DefElem *dcreatedb = NULL; DefElem *dcreatedb = NULL;
DefElem *dcreateuser = NULL; DefElem *dcreateuser = NULL;
DefElem *dgroupElts = NULL; DefElem *dgroupElts = NULL;
DefElem *dvalidUntil = NULL; DefElem *dvalidUntil = NULL;
/* Extract options from the statement node tree */ /* Extract options from the statement node tree */
foreach(option, stmt->options) foreach(option, stmt->options)
{ {
DefElem *defel = (DefElem *) lfirst(option); DefElem *defel = (DefElem *) lfirst(option);
if (strcasecmp(defel->defname, "password") == 0) { if (strcasecmp(defel->defname, "password") == 0 ||
if (dpassword) strcasecmp(defel->defname, "encryptedPassword") == 0 ||
elog(ERROR, "CREATE USER: conflicting options"); strcasecmp(defel->defname, "unencryptedPassword") == 0) {
dpassword = defel; if (dpassword)
} elog(ERROR, "CREATE USER: conflicting options");
else if (strcasecmp(defel->defname, "sysid") == 0) { dpassword = defel;
if (dsysid) if (strcasecmp(defel->defname, "encryptedPassword") == 0)
elog(ERROR, "CREATE USER: conflicting options"); encrypt_password = true;
dsysid = defel; else if (strcasecmp(defel->defname, "unencryptedPassword") == 0)
} encrypt_password = false;
else if (strcasecmp(defel->defname, "createdb") == 0) { }
if (dcreatedb) else if (strcasecmp(defel->defname, "sysid") == 0) {
elog(ERROR, "CREATE USER: conflicting options"); if (dsysid)
dcreatedb = defel; elog(ERROR, "CREATE USER: conflicting options");
} dsysid = defel;
else if (strcasecmp(defel->defname, "createuser") == 0) { }
if (dcreateuser) else if (strcasecmp(defel->defname, "createdb") == 0) {
elog(ERROR, "CREATE USER: conflicting options"); if (dcreatedb)
dcreateuser = defel; elog(ERROR, "CREATE USER: conflicting options");
} dcreatedb = defel;
else if (strcasecmp(defel->defname, "groupElts") == 0) { }
if (dgroupElts) else if (strcasecmp(defel->defname, "createuser") == 0) {
elog(ERROR, "CREATE USER: conflicting options"); if (dcreateuser)
dgroupElts = defel; elog(ERROR, "CREATE USER: conflicting options");
} dcreateuser = defel;
else if (strcasecmp(defel->defname, "validUntil") == 0) { }
if (dvalidUntil) else if (strcasecmp(defel->defname, "groupElts") == 0) {
elog(ERROR, "CREATE USER: conflicting options"); if (dgroupElts)
dvalidUntil = defel; elog(ERROR, "CREATE USER: conflicting options");
} dgroupElts = defel;
else }
elog(ERROR,"CREATE USER: option \"%s\" not recognized", else if (strcasecmp(defel->defname, "validUntil") == 0) {
defel->defname); if (dvalidUntil)
} elog(ERROR, "CREATE USER: conflicting options");
dvalidUntil = defel;
}
else
elog(ERROR,"CREATE USER: option \"%s\" not recognized",
defel->defname);
}
if (dcreatedb) if (dcreatedb)
createdb = intVal(dcreatedb->arg) != 0; createdb = intVal(dcreatedb->arg) != 0;
if (dcreateuser) if (dcreateuser)
createuser = intVal(dcreateuser->arg) != 0; createuser = intVal(dcreateuser->arg) != 0;
if (dsysid) if (dsysid)
{ {
sysid = intVal(dsysid->arg); sysid = intVal(dsysid->arg);
havesysid = true; havesysid = true;
} }
if (dvalidUntil) if (dvalidUntil)
validUntil = strVal(dvalidUntil->arg); validUntil = strVal(dvalidUntil->arg);
if (dpassword) if (dpassword)
password = strVal(dpassword->arg); password = strVal(dpassword->arg);
if (dgroupElts) if (dgroupElts)
groupElts = (List *) dgroupElts->arg; groupElts = (List *) dgroupElts->arg;
/* Check some permissions first */ /* Check some permissions first */
@ -337,8 +346,18 @@ CreateUser(CreateUserStmt *stmt)
new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser); new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser);
if (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));
}
}
if (validUntil) if (validUntil)
new_record[Anum_pg_shadow_valuntil - 1] = new_record[Anum_pg_shadow_valuntil - 1] =
DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil)); DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil));
@ -418,6 +437,8 @@ AlterUser(AlterUserStmt *stmt)
bool null; bool null;
List *option; List *option;
char *password = NULL; /* PostgreSQL user password */ 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 createdb = -1; /* Can the user create databases? */
int createuser = -1; /* Can this user create users? */ int createuser = -1; /* Can this user create users? */
char *validUntil = NULL; /* The time the login is valid until */ char *validUntil = NULL; /* The time the login is valid until */
@ -431,10 +452,16 @@ AlterUser(AlterUserStmt *stmt)
{ {
DefElem *defel = (DefElem *) lfirst(option); 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) if (dpassword)
elog(ERROR, "ALTER USER: conflicting options"); elog(ERROR, "ALTER USER: conflicting options");
dpassword = defel; 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) { else if (strcasecmp(defel->defname, "createdb") == 0) {
if (dcreatedb) if (dcreatedb)
@ -445,17 +472,17 @@ AlterUser(AlterUserStmt *stmt)
if (dcreateuser) if (dcreateuser)
elog(ERROR, "ALTER USER: conflicting options"); elog(ERROR, "ALTER USER: conflicting options");
dcreateuser = defel; dcreateuser = defel;
} }
else if (strcasecmp(defel->defname, "validUntil") == 0) { else if (strcasecmp(defel->defname, "validUntil") == 0) {
if (dvalidUntil) if (dvalidUntil)
elog(ERROR, "ALTER USER: conflicting options"); elog(ERROR, "ALTER USER: conflicting options");
dvalidUntil = defel; dvalidUntil = defel;
} }
else else
elog(ERROR,"ALTER USER: option \"%s\" not recognized", elog(ERROR,"ALTER USER: option \"%s\" not recognized",
defel->defname); defel->defname);
} }
if (dcreatedb) if (dcreatedb)
createdb = intVal(dcreatedb->arg); createdb = intVal(dcreatedb->arg);
if (dcreateuser) if (dcreateuser)
@ -464,8 +491,8 @@ AlterUser(AlterUserStmt *stmt)
validUntil = strVal(dvalidUntil->arg); validUntil = strVal(dvalidUntil->arg);
if (dpassword) if (dpassword)
password = strVal(dpassword->arg); password = strVal(dpassword->arg);
if (password) if (password)
CheckPgUserAclNotNull(); CheckPgUserAclNotNull();
/* must be superuser or just want to change your own password */ /* must be superuser or just want to change your own password */
@ -552,8 +579,16 @@ AlterUser(AlterUserStmt *stmt)
/* password */ /* password */
if (password) if (password)
{ {
new_record[Anum_pg_shadow_passwd - 1] = if (!encrypt_password || isMD5(password))
DirectFunctionCall1(textin, CStringGetDatum(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] = ' '; new_record_nulls[Anum_pg_shadow_passwd - 1] = ' ';
} }
else else
@ -793,40 +828,40 @@ CreateGroup(CreateGroupStmt *stmt)
Datum new_record[Natts_pg_group]; Datum new_record[Natts_pg_group];
char new_record_nulls[Natts_pg_group]; char new_record_nulls[Natts_pg_group];
List *item, List *item,
*option, *option,
*newlist = NIL; *newlist = NIL;
ArrayType *userarray; ArrayType *userarray;
int sysid = 0; int sysid = 0;
List *userElts = NIL; List *userElts = NIL;
DefElem *dsysid = NULL; DefElem *dsysid = NULL;
DefElem *duserElts = NULL; DefElem *duserElts = NULL;
foreach(option, stmt->options) foreach(option, stmt->options)
{ {
DefElem *defel = (DefElem *) lfirst(option); DefElem *defel = (DefElem *) lfirst(option);
if (strcasecmp(defel->defname, "sysid") == 0) { if (strcasecmp(defel->defname, "sysid") == 0) {
if (dsysid) if (dsysid)
elog(ERROR, "CREATE GROUP: conflicting options"); elog(ERROR, "CREATE GROUP: conflicting options");
dsysid = defel; dsysid = defel;
} }
else if (strcasecmp(defel->defname, "userElts") == 0) { else if (strcasecmp(defel->defname, "userElts") == 0) {
if (duserElts) if (duserElts)
elog(ERROR, "CREATE GROUP: conflicting options"); elog(ERROR, "CREATE GROUP: conflicting options");
duserElts = defel; duserElts = defel;
} }
else else
elog(ERROR,"CREATE GROUP: option \"%s\" not recognized", elog(ERROR,"CREATE GROUP: option \"%s\" not recognized",
defel->defname); defel->defname);
} }
if (dsysid) if (dsysid)
{ {
sysid = intVal(dsysid->arg); sysid = intVal(dsysid->arg);
havesysid = true; havesysid = true;
} }
if (duserElts) if (duserElts)
userElts = (List *) duserElts->arg; userElts = (List *) duserElts->arg;
/* /*

View File

@ -4,7 +4,7 @@
# Makefile for libpq subsystem (backend half of libpq interface) # Makefile for libpq subsystem (backend half of libpq interface)
# #
# IDENTIFICATION # 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 # be-fsstubs is here for historical reasons, probably belongs elsewhere
OBJS = be-fsstubs.o \ 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 pqcomm.o pqformat.o pqpacket.o pqsignal.o util.o

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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"; authmethod = "IDENT";
break; break;
case uaPassword: case uaPassword:
authmethod = "Password";
break;
case uaCrypt: case uaCrypt:
case uaMD5:
authmethod = "Password"; authmethod = "Password";
break; break;
} }
@ -507,6 +506,11 @@ ClientAuthentication(Port *port)
status = recv_and_check_password_packet(port); status = recv_and_check_password_packet(port);
break; break;
case uaMD5:
sendAuthRequest(port, AUTH_REQ_MD5);
status = recv_and_check_password_packet(port);
break;
case uaTrust: case uaTrust:
status = STATUS_OK; status = STATUS_OK;
break; break;
@ -532,7 +536,7 @@ sendAuthRequest(Port *port, AuthRequest areq)
pq_sendint(&buf, (int32) areq, sizeof(int32)); pq_sendint(&buf, (int32) areq, sizeof(int32));
/* Add the salt for encrypted passwords. */ /* 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[0], 1);
pq_sendint(&buf, port->salt[1], 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) if (pq_eof() == EOF || pq_getint(&len, 4) == EOF)
return STATUS_ERROR; /* client didn't want to send password */ return STATUS_ERROR; /* client didn't want to send password */
initStringInfo(&buf); initStringInfo(&buf);
pq_getstr(&buf); pq_getstr(&buf); /* receive password */
if (DebugLvl) if (DebugLvl)
fprintf(stderr, "received password packet with len=%d, pw=%s\n", 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') if (port->auth_arg[0] != '\0')
return verify_password(port, user, password); 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; MsgType msgtype = (MsgType) port->proto;
/* Handle the authentication that's offered. */ /* Handle the authentication that's offered. */
switch (msgtype) switch (msgtype)
{ {
case STARTUP_KRB4_MSG: case STARTUP_KRB4_MSG:
@ -634,6 +637,7 @@ map_old_to_new(Port *port, UserAuth old, int status)
switch (port->auth_method) switch (port->auth_method)
{ {
case uaCrypt: case uaCrypt:
case uaMD5:
case uaReject: case uaReject:
status = STATUS_ERROR; status = STATUS_ERROR;
break; break;

View File

@ -9,7 +9,7 @@
* Dec 17, 1997 - Todd A. Brandys * Dec 17, 1997 - Todd A. Brandys
* Orignal Version Completed. * 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 "postgres.h"
#include "libpq/crypt.h" #include "libpq/crypt.h"
#include "libpq/md5.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "storage/fd.h" #include "storage/fd.h"
#include "utils/nabstime.h" #include "utils/nabstime.h"
@ -254,7 +255,7 @@ crypt_getloginfo(const char *user, char **passwd, char **valuntil)
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
int 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, 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 * Compare with the encrypted or plain password depending on the
* authentication method being used for this connection. * authentication method being used for this connection.
*/ */
switch (port->auth_method)
{
case uaCrypt:
crypt_pwd = crypt(passwd, port->salt);
break;
case uaMD5:
crypt_pwd = palloc(MD5_PASSWD_LEN+1);
crypt_pwd = if (isMD5(passwd))
(port->auth_method == uaCrypt ? crypt(passwd, port->salt) : 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)) if (!strcmp(pgpass, crypt_pwd))
{ {
@ -302,9 +341,11 @@ crypt_verify(const Port *port, const char *user, const char *pgpass)
retval = STATUS_OK; retval = STATUS_OK;
} }
pfree((void *) passwd); pfree(passwd);
if (valuntil) if (valuntil)
pfree((void *) valuntil); pfree(valuntil);
if (port->auth_method == uaMD5)
pfree(crypt_pwd);
return retval; return retval;
} }

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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. * *error_p. line points to the next token of the line.
*/ */
static void static void
parse_hba_auth(List *line, UserAuth *userauth_p, char *auth_arg, parse_hba_auth(List *line, ProtocolVersion proto, UserAuth *userauth_p,
bool *error_p) char *auth_arg, bool *error_p)
{ {
char *token; char *token;
@ -227,7 +227,15 @@ parse_hba_auth(List *line, UserAuth *userauth_p, char *auth_arg,
else if (strcmp(token, "reject") == 0) else if (strcmp(token, "reject") == 0)
*userauth_p = uaReject; *userauth_p = uaReject;
else if (strcmp(token, "crypt") == 0) 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 else
*error_p = true; *error_p = true;
line = lnext(line); line = lnext(line);
@ -285,7 +293,8 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
line = lnext(line); line = lnext(line);
if (!line) if (!line)
goto hba_syntax; 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) if (*error_p)
goto hba_syntax; goto hba_syntax;
@ -354,7 +363,8 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
line = lnext(line); line = lnext(line);
if (!line) if (!line)
goto hba_syntax; 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) if (*error_p)
goto hba_syntax; goto hba_syntax;

View File

@ -2,7 +2,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * the current code needs non-encrypted passwords to
* encrypt with a random salt. * encrypt with a random salt.
*/ */
if (port->auth_method == uaCrypt if (port->auth_method == uaCrypt ||
|| test_pw == NULL || test_pw[0] == '\0' port->auth_method == uaMD5 ||
|| strcmp(test_pw, "+") == 0) test_pw == NULL ||
return crypt_verify(port, user, password); 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) if (strcmp(crypt(password, test_pw), test_pw) == 0)
{ {
/* it matched. */ /* it matched. */

View File

@ -3,7 +3,6 @@
# #
# #
# This file controls: # This file controls:
#
# o which hosts are allowed to connect # o which hosts are allowed to connect
# o how users are authenticated on each host # o how users are authenticated on each host
# o databases accessible by each host # o databases accessible by each host
@ -24,7 +23,6 @@
# ============ # ============
# #
# There are three types of records: # There are three types of records:
#
# o host # o host
# o hostssl # o hostssl
# o local # o local
@ -40,7 +38,6 @@
# host DBNAME IP_ADDRESS ADDRESS_MASK AUTH_TYPE [AUTH_ARGUMENT] # host DBNAME IP_ADDRESS ADDRESS_MASK AUTH_TYPE [AUTH_ARGUMENT]
# #
# DBNAME can be: # DBNAME can be:
#
# o the name of a PostgreSQL database # o the name of a PostgreSQL database
# o "all" to indicate all databases # o "all" to indicate all databases
# o "sameuser" to allow access only to databases with the same # o "sameuser" to allow access only to databases with the same
@ -80,7 +77,6 @@
# allowed only if this record type appears. # allowed only if this record type appears.
# #
# Format: # Format:
#
# local DBNAME AUTH_TYPE [AUTH_ARGUMENT] # local DBNAME AUTH_TYPE [AUTH_ARGUMENT]
# #
# This format is identical to the "host" record type except the IP_ADDRESS # This format is identical to the "host" record type except the IP_ADDRESS
@ -219,4 +215,3 @@
local all trust local all trust
host all 127.0.0.1 255.255.255.255 trust host all 127.0.0.1 255.255.255.255 trust

View File

@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -306,7 +306,7 @@ static void doNegateFloat(Value *v);
CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR, CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC,
DISTINCT, DOUBLE, DROP, 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, FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
GLOBAL, GRANT, GROUP, HAVING, HOUR_P, GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS, 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, SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME, SUBSTRING,
TABLE, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR, TABLE, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR,
TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P, 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, VALUES, VARCHAR, VARYING, VIEW,
WHEN, WHERE, WITH, WORK, YEAR_P, ZONE WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
@ -558,6 +558,18 @@ OptUserElem: PASSWORD Sconst
$$->defname = "password"; $$->defname = "password";
$$->arg = (Node *)makeString($2); $$->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 | SYSID Iconst
{ {
$$ = makeNode(DefElem); $$ = makeNode(DefElem);
@ -5765,6 +5777,7 @@ ColLabel: ColId { $$ = $1; }
| DISTINCT { $$ = "distinct"; } | DISTINCT { $$ = "distinct"; }
| DO { $$ = "do"; } | DO { $$ = "do"; }
| ELSE { $$ = "else"; } | ELSE { $$ = "else"; }
| ENCRYPTED { $$ = "encrypted"; }
| END_TRANS { $$ = "end"; } | END_TRANS { $$ = "end"; }
| EXCEPT { $$ = "except"; } | EXCEPT { $$ = "except"; }
| EXISTS { $$ = "exists"; } | EXISTS { $$ = "exists"; }
@ -5836,6 +5849,7 @@ ColLabel: ColId { $$ = $1; }
| TRANSACTION { $$ = "transaction"; } | TRANSACTION { $$ = "transaction"; }
| TRIM { $$ = "trim"; } | TRIM { $$ = "trim"; }
| TRUE_P { $$ = "true"; } | TRUE_P { $$ = "true"; }
| UNENCRYPTED { $$ = "unencrypted"; }
| UNION { $$ = "union"; } | UNION { $$ = "union"; }
| UNIQUE { $$ = "unique"; } | UNIQUE { $$ = "unique"; }
| UNKNOWN { $$ = "unknown"; } | UNKNOWN { $$ = "unknown"; }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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}, {"each", EACH},
{"else", ELSE}, {"else", ELSE},
{"encoding", ENCODING}, {"encoding", ENCODING},
{"encrypted", ENCRYPTED},
{"end", END_TRANS}, {"end", END_TRANS},
{"escape", ESCAPE}, {"escape", ESCAPE},
{"except", EXCEPT}, {"except", EXCEPT},
@ -262,6 +263,7 @@ static ScanKeyword ScanKeywords[] = {
{"truncate", TRUNCATE}, {"truncate", TRUNCATE},
{"trusted", TRUSTED}, {"trusted", TRUSTED},
{"type", TYPE_P}, {"type", TYPE_P},
{"unencrypted", UNENCRYPTED},
{"union", UNION}, {"union", UNION},
{"unique", UNIQUE}, {"unique", UNIQUE},
{"unknown", UNKNOWN}, {"unknown", UNKNOWN},

View File

@ -4,7 +4,7 @@
* Support for grand unified configuration scheme, including SET * Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options. * 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 * Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
@ -80,6 +80,8 @@ bool SQL_inheritance = true;
bool Australian_timezones = false; bool Australian_timezones = false;
bool Password_encryption = false;
#ifndef PG_KRB_SRVTAB #ifndef PG_KRB_SRVTAB
#define PG_KRB_SRVTAB "" #define PG_KRB_SRVTAB ""
#endif #endif
@ -246,11 +248,12 @@ static struct config_bool
{"sql_inheritance", PGC_USERSET, &SQL_inheritance, true, NULL}, {"sql_inheritance", PGC_USERSET, &SQL_inheritance, true, NULL},
{"australian_timezones", PGC_USERSET, &Australian_timezones, {"australian_timezones", PGC_USERSET, &Australian_timezones, false, ClearDateCache},
false, ClearDateCache},
{"fixbtree", PGC_POSTMASTER, &FixBTree, true, NULL}, {"fixbtree", PGC_POSTMASTER, &FixBTree, true, NULL},
{"password_encryption", PGC_USERSET, &Password_encryption, false, NULL},
{NULL, 0, NULL, false, NULL} {NULL, 0, NULL, false, NULL}
}; };

View File

@ -176,9 +176,10 @@
# #
# Misc # Misc
# #
#default_transaction_isolation = 'read committed'
#sql_inheritance = true
#australian_timezones = false #australian_timezones = false
#deadlock_timeout = 1000 #deadlock_timeout = 1000
#default_transaction_isolation = 'read committed'
#max_expr_depth = 10000 # min 10 #max_expr_depth = 10000 # min 10
#password_encryption = false
#sql_inheritance = true

View File

@ -22,10 +22,6 @@ extern int pwd_cache_count;
extern char *crypt_getpwdfilename(void); extern char *crypt_getpwdfilename(void);
extern char *crypt_getpwdreloadfilename(void); extern char *crypt_getpwdreloadfilename(void);
#ifdef NOT_USED extern int md5_crypt_verify(const Port *port, const char *user, const char *pgpass);
extern MsgType crypt_salt(const char *user);
#endif
extern int crypt_verify(const Port *port, const char *user, const char *pgpass);
#endif #endif

View File

@ -4,7 +4,7 @@
* Interface to hba.c * 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, uaTrust,
uaIdent, uaIdent,
uaPassword, uaPassword,
uaCrypt uaCrypt,
uaMD5 /* This starts as uaCrypt from pg_hba.conf, but gets
overridden if the client supports MD5 */
} UserAuth; } UserAuth;
typedef struct Port hbaPort; typedef struct Port hbaPort;

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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. */ /* The earliest and latest frontend/backend protocol version supported. */
#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(0,0) #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 * 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. */ /* 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_KRB4 1 /* Kerberos V4 */
#define AUTH_REQ_KRB5 2 /* Kerberos V5 */ #define AUTH_REQ_KRB5 2 /* Kerberos V5 */
#define AUTH_REQ_PASSWORD 3 /* Password */ #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; typedef uint32 AuthRequest;

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* some of the information in this file should be moved to * some of the information in this file should be moved to
@ -171,8 +171,10 @@ extern bool enableFsync;
extern bool allowSystemTableMods; extern bool allowSystemTableMods;
extern int SortMem; 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 NetServer;
extern bool EnableSSL; extern bool EnableSSL;

View File

@ -4,7 +4,7 @@
# #
# Copyright (c) 1994, Regents of the University of California # 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)"' 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 \ 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) $(INET_ATON) $(SNPRINTF) $(STRERROR)
ifdef MULTIBYTE 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)) 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 # Shared library stuff
include $(top_srcdir)/src/Makefile.shlib include $(top_srcdir)/src/Makefile.shlib
@ -49,6 +49,12 @@ backend_src = $(top_srcdir)/src/backend
dllist.c: $(backend_src)/lib/dllist.c dllist.c: $(backend_src)/lib/dllist.c
rm -f $@ && $(LN_S) $< . 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() # this only gets done if configure finds system doesn't have inet_aton()
inet_aton.c: $(backend_src)/port/inet_aton.c inet_aton.c: $(backend_src)/port/inet_aton.c
rm -f $@ && $(LN_S) $< . rm -f $@ && $(LN_S) $< .
@ -82,7 +88,7 @@ uninstall: uninstall-lib
rm -f $(addprefix $(DESTDIR)$(includedir)/, libpq-fe.h libpq-int.h pqexpbuffer.h) rm -f $(addprefix $(DESTDIR)$(includedir)/, libpq-fe.h libpq-int.h pqexpbuffer.h)
clean distclean maintainer-clean: clean-lib 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 rm -f $(OBJS) inet_aton.c snprintf.c strerror.c
depend dep: depend dep:

View File

@ -10,7 +10,7 @@
* exceed INITIAL_EXPBUFFER_SIZE (currently 256 bytes). * exceed INITIAL_EXPBUFFER_SIZE (currently 256 bytes).
* *
* IDENTIFICATION * 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-fe.h"
#include "libpq-int.h" #include "libpq-int.h"
#include "fe-auth.h" #include "fe-auth.h"
#include "md5.h"
#ifdef WIN32 #ifdef WIN32
#include "win32.h" #include "win32.h"
@ -434,12 +435,52 @@ pg_krb5_sendauth(char *PQerrormsg, int sock,
static int static int
pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq) pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
{ {
int ret;
char *crypt_pwd;
/* Encrypt the password if needed. */ /* Encrypt the password if needed. */
if (areq == AUTH_REQ_CRYPT) switch (areq)
password = crypt(password, conn->salt); {
case AUTH_REQ_CRYPT:
crypt_pwd = crypt(password, conn->salt);
break;
case AUTH_REQ_MD5:
{
char *crypt_pwd2;
return pqPacketSend(conn, password, strlen(password) + 1); 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;
}
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_PASSWORD:
case AUTH_REQ_CRYPT: case AUTH_REQ_CRYPT:
case AUTH_REQ_MD5:
if (password == NULL || *password == '\0') if (password == NULL || *password == '\0')
{ {
(void) sprintf(PQerrormsg, (void) sprintf(PQerrormsg,
@ -506,9 +548,7 @@ fe_sendauth(AuthRequest areq, PGconn *conn, const char *hostname,
"fe_sendauth: error sending password authentication\n"); "fe_sendauth: error sending password authentication\n");
return STATUS_ERROR; return STATUS_ERROR;
} }
break; break;
default: default:
snprintf(PQerrormsg, PQERRORMSG_LENGTH, snprintf(PQerrormsg, PQERRORMSG_LENGTH,
libpq_gettext("authentication method %u not supported\n"), areq); libpq_gettext("authentication method %u not supported\n"), areq);

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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. */ /* 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)) if (pqGetnchar(conn->salt, sizeof(conn->salt), conn))
{ {
@ -1960,7 +1960,7 @@ static void
closePGconn(PGconn *conn) closePGconn(PGconn *conn)
{ {
/* Note that the protocol doesn't allow us to send Terminate /* 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) if (conn->sock >= 0 && conn->status == CONNECTION_OK)
{ {

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 static int
getNotice(PGconn *conn) getNotice(PGconn *conn)
{ {
/* /*
* Since the Notice might be pretty long, we create a temporary * Since the Notice might be pretty long, we create a temporary
* PQExpBuffer rather than using conn->workBuffer. workBuffer is * PQExpBuffer rather than using conn->workBuffer. workBuffer is

View File

@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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. * 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. * POSTGRES backend dependent Constants.

View File

@ -677,7 +677,7 @@ CC_connect(ConnectionClass *self, char do_password)
mylog("auth got 'R'\n"); mylog("auth got 'R'\n");
areq = SOCK_get_int(sock, 4); 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); SOCK_get_n_char(sock, salt, 2);
mylog("areq = %d\n", areq); mylog("areq = %d\n", areq);
@ -717,6 +717,7 @@ CC_connect(ConnectionClass *self, char do_password)
break; break;
case AUTH_REQ_CRYPT: case AUTH_REQ_CRYPT:
case AUTH_REQ_MD5:
self->errormsg = "Password crypt authentication not supported"; self->errormsg = "Password crypt authentication not supported";
self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED;
return 0; 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 CC_get_max_query_len(const ConnectionClass *conn)
{ {
int value; int value;
/* Long Queries in 7.0+ */ /* Long Queries in 7.0+ */
if (PG_VERSION_GE(conn, 7.0)) if (PG_VERSION_GE(conn, 7.0))
value = 0 /* MAX_STATEMENT_LEN */; value = 0 /* MAX_STATEMENT_LEN */;
/* Prior to 7.0 we used 2*BLCKSZ */ /* Prior to 7.0 we used 2*BLCKSZ */
else if (PG_VERSION_GE(conn, 6.5)) else if (PG_VERSION_GE(conn, 6.5))
value = (2 * BLCKSZ); value = (2 * BLCKSZ);
else else
/* Prior to 6.5 we used BLCKSZ */ /* Prior to 6.5 we used BLCKSZ */
value = BLCKSZ; value = BLCKSZ;
return value; return value;
} }

View File

@ -93,6 +93,7 @@ typedef enum
#define AUTH_REQ_KRB5 2 #define AUTH_REQ_KRB5 2
#define AUTH_REQ_PASSWORD 3 #define AUTH_REQ_PASSWORD 3
#define AUTH_REQ_CRYPT 4 #define AUTH_REQ_CRYPT 4
#define AUTH_REQ_MD5 5
/* Startup Packet sizes */ /* Startup Packet sizes */
#define SM_DATABASE 64 #define SM_DATABASE 64