The attached patch should add MD5 support to ODBC. I don't have ODBC
here so I would appreciate if someone would test it and let me know. I
am not considering applying the patch to CVS.
First, apply the patch, which is the first attachment. Second, copy the
second attachment to src/interfaces/odbc/md5.h. Third, copy
src/backend/libpq/md5.c to src/interfaces/odbc/md5.c.
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Index: src/backend/libpq/Makefile
===================================================================
RCS file: /cvsroot/pgsql/src/backend/libpq/Makefile,v
retrieving revision 1.25
diff -c -r1.25 Makefile
*** src/backend/libpq/Makefile 2001/08/15 18:42:14 1.25
--- src/backend/libpq/Makefile 2001/11/08 19:55:43
***************
*** 19,25 ****
pqcomm.o pqformat.o pqpacket.o pqsignal.o util.o
! all: SUBSYS.o
SUBSYS.o: $(OBJS)
$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
--- 19,30 ----
pqcomm.o pqformat.o pqpacket.o pqsignal.o util.o
! all: check_md5 SUBSYS.o
!
! check_md5:
! @cmp -s md5.c ../../interfaces/odbc/md5.c || \
! (echo "src/interfaces/odbc/md5.c doesn't match src/backend/libpq/md5.c" && \
! exit 1)
SUBSYS.o: $(OBJS)
$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
Index: src/backend/libpq/md5.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/libpq/md5.c,v
retrieving revision 1.9
diff -c -r1.9 md5.c
*** src/backend/libpq/md5.c 2001/10/25 05:49:30 1.9
--- src/backend/libpq/md5.c 2001/11/08 19:55:43
***************
*** 13,21 ****
* $Header: /cvsroot/pgsql/src/backend/libpq/md5.c,v 1.9 2001/10/25 05:49:30 momjian Exp $
*/
- #include "postgres.h"
#include "libpq/crypt.h"
#ifdef FRONTEND
#undef palloc
--- 13,25 ----
* $Header: /cvsroot/pgsql/src/backend/libpq/md5.c,v 1.9 2001/10/25 05:49:30 momjian Exp $
*/
+ #ifndef MD5_ODBC
+ #include "postgres.h"
#include "libpq/crypt.h"
+ #else
+ #include "md5.h"
+ #endif
#ifdef FRONTEND
#undef palloc
Index: src/interfaces/odbc/GNUmakefile
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/odbc/GNUmakefile,v
retrieving revision 1.22
diff -c -r1.22 GNUmakefile
*** src/interfaces/odbc/GNUmakefile 2001/10/09 22:32:33 1.22
--- src/interfaces/odbc/GNUmakefile 2001/11/08 19:55:48
***************
*** 19,29 ****
SO_MAJOR_VERSION = 0
SO_MINOR_VERSION = 27
! override CPPFLAGS := -I$(srcdir) $(CPPFLAGS)
OBJS = info.o bind.o columninfo.o connection.o convert.o drvconn.o \
! environ.o execute.o lobj.o misc.o options.o \
pgtypes.o psqlodbc.o qresult.o results.o socket.o parse.o statement.o \
tuple.o tuplelist.o dlg_specific.o odbcapi.o
--- 19,29 ----
SO_MAJOR_VERSION = 0
SO_MINOR_VERSION = 27
! override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) -DFRONTEND -DMD5_ODBC
OBJS = info.o bind.o columninfo.o connection.o convert.o drvconn.o \
! environ.o execute.o lobj.o md5.o misc.o options.o \
pgtypes.o psqlodbc.o qresult.o results.o socket.o parse.o statement.o \
tuple.o tuplelist.o dlg_specific.o odbcapi.o
Index: src/interfaces/odbc/connection.c
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/odbc/connection.c,v
retrieving revision 1.49
diff -c -r1.49 connection.c
*** src/interfaces/odbc/connection.c 2001/11/05 17:46:38 1.49
--- src/interfaces/odbc/connection.c 2001/11/08 19:55:49
***************
*** 762,769 ****
mylog("past flush\n");
break;
- case AUTH_REQ_CRYPT:
case AUTH_REQ_MD5:
self->errormsg = "Password crypt authentication not supported";
self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED;
return 0;
--- 762,814 ----
mylog("past flush\n");
break;
case AUTH_REQ_MD5:
+ {
+ char *crypt_pwd, *crypt_pwd2;
+
+ mylog("in AUTH_REQ_MD5\n");
+ if (ci->password[0] == '\0')
+ {
+ self->errornumber = CONNECTION_NEED_PASSWORD;
+ self->errormsg = "A password is required for this connection.";
+ return -1; /* need password */
+ }
+
+ mylog("past need password\n");
+
+ if (!(crypt_pwd = malloc(MD5_PASSWD_LEN + 1)) ||
+ !(crypt_pwd2 = malloc(MD5_PASSWD_LEN + 1)))
+ {
+ perror("malloc");
+ return 0;
+ }
+
+ if (!EncryptMD5(ci->password, ci->username,
+ strlen(ci->username), crypt_pwd2))
+ {
+ free(crypt_pwd);
+ free(crypt_pwd2);
+ return 0;
+ }
+ if (!EncryptMD5(crypt_pwd2 + strlen("md5"), salt,
+ 4, crypt_pwd))
+ {
+ free(crypt_pwd);
+ free(crypt_pwd2);
+ return 0;
+ }
+ free(crypt_pwd2);
+
+ SOCK_put_int(sock, 4 + strlen(crypt_pwd) + 1, 4);
+ SOCK_put_n_char(sock, crypt_pwd, strlen(crypt_pwd) + 1);
+ SOCK_flush_output(sock);
+ free(crypt_pwd);
+
+ mylog("past flush\n");
+ break;
+ }
+
+ case AUTH_REQ_CRYPT:
self->errormsg = "Password crypt authentication not supported";
self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED;
return 0;
Index: src/interfaces/odbc/connection.h
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/odbc/connection.h,v
retrieving revision 1.36
diff -c -r1.36 connection.h
*** src/interfaces/odbc/connection.h 2001/11/05 17:46:38 1.36
--- src/interfaces/odbc/connection.h 2001/11/08 19:55:49
***************
*** 286,292 ****
#define CONN_DONT_OVERWRITE 0
#define CONN_OVERWRITE 1
-
/* prototypes */
ConnectionClass *CC_Constructor(void);
char CC_Destructor(ConnectionClass *self);
--- 286,291 ----
Index: src/interfaces/odbc/win32.mak
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/odbc/win32.mak,v
retrieving revision 1.7
diff -c -r1.7 win32.mak
*** src/interfaces/odbc/win32.mak 2001/11/05 09:46:17 1.7
--- src/interfaces/odbc/win32.mak 2001/11/08 19:55:50
***************
*** 67,72 ****
--- 67,73 ----
-@erase "$(INTDIR)\gpps.obj"
-@erase "$(INTDIR)\info.obj"
-@erase "$(INTDIR)\lobj.obj"
+ -@erase "$(INTDIR)\md5.obj"
-@erase "$(INTDIR)\misc.obj"
!IF "$(CFG)" == "MultibyteRelease"
-@erase "$(INTDIR)\multibyte.obj"
***************
*** 152,157 ****
--- 153,159 ----
"$(INTDIR)\gpps.obj" \
"$(INTDIR)\info.obj" \
"$(INTDIR)\lobj.obj" \
+ "$(INTDIR)\md5.obj" \
"$(INTDIR)\misc.obj" \
!IF "$(CFG)" == "MultibyteRelease"
"$(INTDIR)\multibyte.obj" \
***************
*** 200,205 ****
--- 202,208 ----
-@erase "$(INTDIR)\gpps.obj"
-@erase "$(INTDIR)\info.obj"
-@erase "$(INTDIR)\lobj.obj"
+ -@erase "$(INTDIR)\md5.obj"
-@erase "$(INTDIR)\misc.obj"
!IF "$(CFG)" == "MultibyteDebug"
-@erase "$(INTDIR)\multibyte.obj"
***************
*** 288,293 ****
--- 291,297 ----
"$(INTDIR)\gpps.obj" \
"$(INTDIR)\info.obj" \
"$(INTDIR)\lobj.obj" \
+ "$(INTDIR)\md5.obj" \
"$(INTDIR)\misc.obj" \
!IF "$(CFG)" == "MultibyteDebug"
"$(INTDIR)\multibyte.obj" \
***************
*** 379,384 ****
--- 383,394 ----
"$(INTDIR)\lobj.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+ SOURCE=md5.c
+
+ "$(INTDIR)\md5.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) /D "FONTEND" /D "MD5_ODBC" $(CPP_PROJ) $(SOURCE)
SOURCE=misc.c
/* File: connection.h
*
* Description: See "connection.c"
*
* Comments: See "notice.txt" for copyright and license information.
*
*/
#ifndef __MD5_H__
#define __MD5_H__
#include "psqlodbc.h"
#include <stdlib.h>
#include <string.h>
#define MD5_PASSWD_LEN 35
/* From c.h */
#ifndef __BEOS__
#ifndef __cplusplus
#ifndef bool
typedef char bool;
#endif
#ifndef true
#define true ((bool) 1)
#endif
#ifndef false
#define false ((bool) 0)
#endif
#endif /* not C++ */
#endif /* __BEOS__ */
#ifndef __BEOS__ /* this shouldn't be required, but is is! */
typedef unsigned char uint8; /* == 8 bits */
typedef unsigned short uint16; /* == 16 bits */
typedef unsigned int uint32; /* == 32 bits */
#endif /* __BEOS__ */
extern bool EncryptMD5(const char *passwd, const char *salt,
size_t salt_len, char *buf);
#endif