Thread: MD5 support for ODBC
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
Bruce Momjian wrote: > > 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. I checked it under Windows and it worked well. I already committed the interfaces/odbc part. Thanks. Hiroshi Inoue
> Bruce Momjian wrote: > > > > 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. > > I checked it under Windows and it worked well. > I already committed the interfaces/odbc part. OK, great. I am surprised it worked the first time. I didn't test it here, and I am know more for my persistance than skill. :-) I have applied the rest of the patch. It adds a check to the backend/libpq Makefile and aborts if the two C md5.c files are not identical. There are two copies of md5.c because odbc has to be compile-able on its own, and md5.c is also used by the backend and libpq. With this check, the two files will remain in sync because it will not even compile if they aren't. Also, odbc/md5.h has copies of certain definitions that normally appear in include/c.h. Because md5.c must compile alone in the odbc directory, I needed those defines pulled out and added into odbc. I will document that these defines also appear in odbc/md5.h. -- 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
Bruce Momjian writes: > ! 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) Nope, this doesn't work. The source directory is not necessarily the current directory. I don't think it's particularly useful to put checks of static source files in the build path. There are quite a number of places that need to be synchronized manually and there is no check anywhere. It would probably have been better to have one master copy of the file and symlink it to whereever else it is needed. (See libpq Makefile for several examples.) -- Peter Eisentraut peter_e@gmx.net
> Bruce Momjian writes: > > > ! 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) > > Nope, this doesn't work. The source directory is not necessarily the > current directory. OK, I will remove it. However, many of our Makefiles that do ../.. so I assume they have to assume which directory they are in, i.e, from libpq/Makefile: subdir = src/interfaces/libpq top_builddir = ../../.. include $(top_builddir)/src/Makefile.global Also, should we add such checks to the other files that must remain identical? > I don't think it's particularly useful to put checks of static source > files in the build path. There are quite a number of places that need to > be synchronized manually and there is no check anywhere. It would > probably have been better to have one master copy of the file and symlink > it to whereever else it is needed. (See libpq Makefile for several > examples.) Yes, I already do a symlink for md5.c in libpq. The problem is that ODBC has to compile stand-alone, with no reference to any outside directory. I assume that includes symlinks so you can take just /odbc, put it on a Win32 partition, and compile it. I don't want md5.c to change that capability. -- 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
Bruce Momjian wrote: > > > I don't think it's particularly useful to put checks of static source > > files in the build path. There are quite a number of places that need to > > be synchronized manually and there is no check anywhere. It would > > probably have been better to have one master copy of the file and symlink > > it to whereever else it is needed. (See libpq Makefile for several > > examples.) > > Yes, I already do a symlink for md5.c in libpq. The problem is that > ODBC has to compile stand-alone, with no reference to any outside > directory. I assume that includes symlinks so you can take just /odbc, > put it on a Win32 partition, and compile it. I don't want md5.c to > change that capability. Yes I don't love any reference to any outside directory. If a backward incompatible change is made, I don't use it exactly any longer. regards, Hiroshi Inoue
> Bruce Momjian wrote: > > > > > I don't think it's particularly useful to put checks of static source > > > files in the build path. There are quite a number of places that need to > > > be synchronized manually and there is no check anywhere. It would > > > probably have been better to have one master copy of the file and symlink > > > it to whereever else it is needed. (See libpq Makefile for several > > > examples.) > > > > Yes, I already do a symlink for md5.c in libpq. The problem is that > > ODBC has to compile stand-alone, with no reference to any outside > > directory. I assume that includes symlinks so you can take just /odbc, > > put it on a Win32 partition, and compile it. I don't want md5.c to > > change that capability. > > Yes I don't love any reference to any outside directory. > If a backward incompatible change is made, I don't use > it exactly any longer. I will keep it as you see it now --- a separate file in /odbc. -- 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
Bruce Momjian writes: > > Nope, this doesn't work. The source directory is not necessarily the > > current directory. > > OK, I will remove it. However, many of our Makefiles that do ../.. The *build* directory is always the current directory, so '..' stuff is okay to refer to built files. But to reference source files you need to start with $(srcdir) or $(top_srcdir), whichever is convenient. > Also, should we add such checks to the other files that must remain > identical? I don't think we have any others that must remain identical per se. In general, checks for source code sanity are okay, but if you want them in a makefile they should be under the maintainer-check target, not in the build path. However, since there is very little that merits an automated check of this sort, I doubt very many people would actually run this target. > Yes, I already do a symlink for md5.c in libpq. The problem is that > ODBC has to compile stand-alone, with no reference to any outside > directory. Okay, that's reasonable. I think making a note in the file under odbc/ should be sufficient. Possibly include which CVS revision of the original the copy is based on, so one can see when it needs updating. Also, a note in the venerable RELEASE_CHANGES file seems appropriate. -- Peter Eisentraut peter_e@gmx.net
> Bruce Momjian writes: > > > > Nope, this doesn't work. The source directory is not necessarily the > > > current directory. > > > > OK, I will remove it. However, many of our Makefiles that do ../.. > > The *build* directory is always the current directory, so '..' stuff is > okay to refer to built files. But to reference source files you need to > start with $(srcdir) or $(top_srcdir), whichever is convenient. Oh, OK. > > Also, should we add such checks to the other files that must remain > > identical? > > I don't think we have any others that must remain identical per se. > > In general, checks for source code sanity are okay, but if you want them > in a makefile they should be under the maintainer-check target, not in the > build path. However, since there is very little that merits an automated > check of this sort, I doubt very many people would actually run this > target. > OK, removed. > > Yes, I already do a symlink for md5.c in libpq. The problem is that > > ODBC has to compile stand-alone, with no reference to any outside > > directory. > > Okay, that's reasonable. I think making a note in the file under odbc/ > should be sufficient. Possibly include which CVS revision of the original > the copy is based on, so one can see when it needs updating. Also, a note > in the venerable RELEASE_CHANGES file seems appropriate. I am not sure if it is even worth it there. I can't imagine anyone changing md5.c anyway. -- 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