*** raddb/dictionary.orig	Thu Oct 26 18:18:30 2000
--- raddb/dictionary	Thu Oct 26 18:19:19 2000
***************
*** 120,125 ****
--- 120,126 ----
  ATTRIBUTE	Pam-Auth		1041	string
  ATTRIBUTE	Login-Time		1042	string
  ATTRIBUTE	Realm			1045	string
+ ATTRIBUTE	NS-MTA-MD5-Password	1054	string
  
  #
  #	Non-Protocol Attributes
***************
*** 238,243 ****
--- 239,245 ----
  #
  #	Cistron extensions
  #
+ VALUE		Auth-Type		NS-MTA-MD5		252
  VALUE		Auth-Type		Pam			253
  VALUE		Auth-Type		Accept			254
  
*** src/Make.inc.orig	Thu Oct 26 17:21:52 2000
--- src/Make.inc	Thu Oct 26 17:22:52 2000
***************
*** 8,20 ****
  
  SERVER_OBJS    = radiusd.o dict.o files.o util.o md5.o attrprint.o \
  			acct.o radius.o pam.o log.o version.o proxy.o \
! 			exec.o auth.o timestr.o cache.o
  SERVERDBM_OBJS = radiusddbm.o dict.o filesdbm.o util.o md5.o attrprint.o \
  			acct.o radius.o pam.o log.o versiondbm.o proxy.o \
! 			exec.o auth.o timestr.o cache.o
  SERVER_SRCS    = radiusd.c dict.c files.c util.c md5.c attrprint.c acct.c \
  			radius.c pam.c log.c version.c proxy.c \
! 			exec.c auth.c timestr.c cache.c
  INCLUDES       = radius.h conf.h
  
  all:	radiusd radwho radzap raduse radtest
--- 8,20 ----
  
  SERVER_OBJS    = radiusd.o dict.o files.o util.o md5.o attrprint.o \
  			acct.o radius.o pam.o log.o version.o proxy.o \
! 			exec.o auth.o timestr.o cache.o ns_mta_md5.o
  SERVERDBM_OBJS = radiusddbm.o dict.o filesdbm.o util.o md5.o attrprint.o \
  			acct.o radius.o pam.o log.o versiondbm.o proxy.o \
! 			exec.o auth.o timestr.o cache.o ns_mta_md5.o
  SERVER_SRCS    = radiusd.c dict.c files.c util.c md5.c attrprint.c acct.c \
  			radius.c pam.c log.c version.c proxy.c \
! 			exec.c auth.c timestr.c cache.c ns_mta_md5.c
  INCLUDES       = radius.h conf.h
  
  all:	radiusd radwho radzap raduse radtest
*** src/auth.c.orig	Thu Oct 26 18:05:57 2000
--- src/auth.c	Fri Oct 27 13:49:01 2000
***************
*** 305,310 ****
--- 305,314 ----
  	 */
  	if ((password_pair = pairfind(check_item, PW_CRYPT_PASSWORD)) != NULL)
  		auth_type = PW_AUTHTYPE_CRYPT;
+ #ifdef NS_MTA_MD5
+ 	else if ((password_pair = pairfind(check_item, PW_NS_MTA_MD5_PASSWORD)) != NULL)
+ 		auth_type = PW_AUTHTYPE_NS_MTA_MD5;
+ #endif
  	else
  		password_pair = pairfind(check_item, PW_PASSWORD);
  
***************
*** 397,402 ****
--- 401,416 ----
  			    crypt(string, password_pair->strvalue)) != 0)
  					result = -1;
  			break;
+ #ifdef NS_MTA_MD5
+ 		case PW_AUTHTYPE_NS_MTA_MD5:
+ 			DEBUG2("  auth: NS-MTA-MD5");
+ 			if (password_pair == NULL) {
+ 				result = string[0] ? -1 : 0;
+ 				break;
+ 			}
+ 			result = ns_mta_md5_pass(string, password_pair->strvalue);
+ 			break;
+ #endif
  		case PW_AUTHTYPE_LOCAL:
  			DEBUG2("  auth: Local");
  			/*
*** src/files.c.orig	Thu Oct 26 18:23:38 2000
--- src/files.c	Fri Oct 27 13:29:09 2000
***************
*** 141,146 ****
--- 141,149 ----
  #ifdef PAM
  		    i->attribute == PAM_AUTH_ATTR ||
  #endif
+ #ifdef NS_MTA_MD5
+ 		    i->attribute == PW_NS_MTA_MD5_PASSWORD ||
+ #endif
  		    i->attribute == PW_CRYPT_PASSWORD)
  			has_password = 1;
  		tailto = i;
***************
*** 161,166 ****
--- 164,172 ----
  #ifdef PAM
  		     i->attribute == PAM_AUTH_ATTR ||
  #endif
+ #ifdef NS_MTA_MD5
+ 		     i->attribute == PW_NS_MTA_MD5_PASSWORD ||
+ #endif
  		     i->attribute == PW_CRYPT_PASSWORD)) {
  			tailfrom = i;
  			continue;
***************
*** 461,466 ****
--- 467,475 ----
  			case PW_AUTHTYPE:
  #ifdef PAM /* cjd 19980706 */
                          case PAM_AUTH_ATTR:
+ #endif
+ #ifdef NS_MTA_MD5
+ 			case PW_NS_MTA_MD5_PASSWORD:
  #endif
  			case PW_SIMULTANEOUS_USE:
  			case PW_STRIP_USERNAME:
*** src/md5.h.orig	Thu Oct 26 18:34:17 2000
--- src/md5.h	Fri Oct 27 11:20:22 2000
***************
*** 21,30 ****
  typedef unsigned short int UINT2;
  
  /* UINT4 defines a four byte word */
! #if defined(__alpha) && (defined(__osf__) || defined(__linux__))
! typedef unsigned int UINT4;
! #else
! typedef unsigned long int UINT4;
  #endif
  
  /* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
--- 21,33 ----
  typedef unsigned short int UINT2;
  
  /* UINT4 defines a four byte word */
! #ifndef _UINT4
!   #define _UINT4
!   #if defined(__alpha) && (defined(__osf__) || defined(__linux__))
!     typedef unsigned int UINT4;
!   #else
!     typedef unsigned long int UINT4;
!   #endif
  #endif
  
  /* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
*** src/ns_mta_md5.c.orig	Thu Oct 26 20:22:11 2000
--- src/ns_mta_md5.c	Fri Oct 27 13:37:31 2000
***************
*** 0 ****
--- 1,114 ----
+ /*
+  * mta_md5.c	Functions to authenticate using NS-MTA-MD5 passwords.
+  *		Taken from the hacks for qmail located at nrg4u.com
+  *		by Andre Oppermann.
+  *
+  *   NS-MTA-MD5 passwords are 64 byte strings, the first  
+  *   32 bytes being the password hash and the last 32 bytes 
+  *   the salt.  The clear text password and the salt are MD5 
+  *   hashed[1].  If the resulting hash concatenated with the salt
+  *   are equivalent to the original NS-MTA-MD5 password the 
+  *   password is correct. 
+  *
+  *   [1] Read the source for details.
+  *
+  */
+ 
+ #ifdef NS_MTA_MD5
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include "md5.h"
+ #include "radiusd.h"
+ 
+ #define HASH_LEN 100
+ 
+ static char * ns_mta_hextab = "0123456789abcdef";
+ 
+ void byte_copy(to,n,from)
+ register char *to;
+ register unsigned int n;
+ register char *from;
+ {
+   for (;;) {
+     if (!n) return; *to++ = *from++; --n;
+     if (!n) return; *to++ = *from++; --n;
+     if (!n) return; *to++ = *from++; --n;
+     if (!n) return; *to++ = *from++; --n;
+   }
+ }
+ 
+ int str_diff(s,t)
+ register char *s;
+ register char *t;
+ {
+   register char x;
+ 
+   for (;;) {
+     x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+     x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+     x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+     x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+   }
+   return ((int)(unsigned int)(unsigned char) x)
+        - ((int)(unsigned int)(unsigned char) *t);
+ }
+ 
+ void
+ ns_mta_hexify(char *buffer, char *str, int len)
+ {
+   char *pch = str;
+   char ch;
+   int i;
+ 
+   for(i = 0;i < len; i ++) {
+     ch = pch[i];
+     buffer[2*i] = ns_mta_hextab[(ch>>4)&15];
+     buffer[2*i+1] = ns_mta_hextab[ch&15];
+   }
+   return;
+ }
+ 
+ char *
+ ns_mta_hash_alg(char *buffer, char *salt, char *passwd)
+ {
+   MD5_CTX context;
+   char saltstr[2048];
+   unsigned char digest[16];
+ 
+   sprintf(saltstr,"%s%c%s%c%s",salt,89,passwd,247,salt);
+ 
+   MD5Init(&context);
+   MD5Update(&context,(unsigned char *)saltstr,strlen(saltstr));
+   MD5Final(digest,&context);
+   ns_mta_hexify(buffer,(char*)digest,16);
+   buffer[32] = '\0';
+   return(buffer);
+ }
+ 
+ int ns_mta_md5_pass(char *clear, char *encrypted)
+ {
+   char hashed[HASH_LEN];
+   char salt[33];
+ 
+   if (!strlen(encrypted) == 64) {
+     DEBUG2("NS-MTA-MD5 hash not 64 bytes");
+     return -1;
+   }
+ 
+   byte_copy(salt, 32, &encrypted[32]);
+   salt[32] = 0;
+   ns_mta_hash_alg(hashed, salt, clear);
+   byte_copy(&hashed[32], 33, salt);
+ 
+   if (!str_diff(hashed,encrypted)) {
+     return 0;
+   }
+ 
+   return -1;
+ 
+ }
+ 
+ #endif /* NS_MTA_MD5 */
*** src/radius.h.orig	Thu Oct 26 18:10:56 2000
--- src/radius.h	Thu Oct 26 18:12:17 2000
***************
*** 135,140 ****
--- 135,141 ----
  #define PAM_AUTH_ATTR			1041
  #define PW_LOGIN_TIME			1042
  #define PW_REALM			1045
+ #define PW_NS_MTA_MD5_PASSWORD		1054
  
  /*
   *	INTEGER TRANSLATIONS
***************
*** 177,182 ****
--- 178,184 ----
  #define PW_AUTHTYPE_SECURID		2
  #define PW_AUTHTYPE_CRYPT		3
  #define PW_AUTHTYPE_REJECT		4
+ #define PW_AUTHTYPE_NS_MTA_MD5		252
  #define PW_AUTHTYPE_PAM			253
  #define PW_AUTHTYPE_ACCEPT		254
  
*** src/sysdep.h.orig	Thu Oct 26 18:37:54 2000
--- src/sysdep.h	Fri Oct 27 11:20:30 2000
***************
*** 14,23 ****
  #  endif
  #endif
  
! #if defined(__alpha) && (defined(__osf__) || defined(__linux__))
! typedef unsigned int	UINT4;
! #else
! typedef unsigned long	UINT4;
  #endif
  
  #ifdef BSD
--- 14,26 ----
  #  endif
  #endif
  
! #ifndef _UINT4
!   #define _UINT4
!   #if defined(__alpha) && (defined(__osf__) || defined(__linux__))
!     typedef unsigned int UINT4;
!   #else
!     typedef unsigned long UINT4;
!   #endif
  #endif
  
  #ifdef BSD
*** src/version.c.orig	Fri Oct 27 14:03:57 2000
--- src/version.c	Fri Oct 27 14:04:24 2000
***************
*** 76,81 ****
--- 76,84 ----
  #if defined(COMPAT_1543)
  	fprintf(stderr, " COMPAT_1543");
  #endif
+ #if defined(NS_MTA_MD5)
+ 	fprintf(stderr, " NS-MTA-MD5");
+ #endif
  
  	/* here are all the system definitions compilation uses */
  #if defined(__alpha)
