Thread: MD5 support for ODBC

MD5 support for ODBC

From
Bruce Momjian
Date:
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

Re: [ODBC] MD5 support for ODBC

From
Hiroshi Inoue
Date:
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

Re: [ODBC] MD5 support for ODBC

From
Bruce Momjian
Date:
> 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

Re: [ODBC] MD5 support for ODBC

From
Peter Eisentraut
Date:
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


Re: [ODBC] MD5 support for ODBC

From
Bruce Momjian
Date:
> 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

Re: [ODBC] MD5 support for ODBC

From
Hiroshi Inoue
Date:
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

Re: [ODBC] MD5 support for ODBC

From
Bruce Momjian
Date:
> 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

Re: [ODBC] MD5 support for ODBC

From
Peter Eisentraut
Date:
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


Re: [ODBC] MD5 support for ODBC

From
Bruce Momjian
Date:
> 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