On Wed, 2002-06-26 at 14:12, Alan DeKok wrote:
> Florin Andrei <[EMAIL PROTECTED]> wrote:
> 
> > Jun 26 12:42:04 7E:diaspar sshd[130755]: pam_radius_auth: DEBUG:
> > getservbyname(radius, udp) returned XXXXXXXXX.
> > Jun 26 12:42:04 3E:diaspar sshd[130755]: pam_radius_auth: packet from
> > RADIUS server XXXXXXXXXXXXXX.sgi.com fails verification: The shared
> > secret is probably incorrect.
> 
>   If the shared secrets *are* correct, then I would suggest checking
> byte order issues in the 'md5.c' file included with the source.  If
> the byte order in MD5 is wrong, then the whole RADIUS infrastructure
> fails.

I attached the patch that makes pam_radius work on SGI Irix.
It's mostly:
- some new lines added to the Makefile
- a conditional added to md5.c (#ifdef sgi)
- some typecasting enforcements all over the code (pam_radius_auth.c)
- the debug messages were changed a little bit (pam_radius_auth.c again)

The reason we added these typecasting things was: MIPSPro is extremely
pedantic, it's going to bitch out loud if you don't match types
correctly. It's a pain in the butt when you want to write a quick hack,
but it works miracles against pointer problems, etc. ;-)

Pre-requisites to compile pam_radius on SGI platforms:
- the freeware PAM package from freeware.sgi.com
- the MIPSPro compiler (gcc does not work yet with pam_radius)
- freeware make (gmake)
For those who don't have MIPSPro (it's not freeware) a binary is here:

ftp://andrei.myip.org/irix/pam_radius/

David Lindes <[EMAIL PROTECTED]> did the changes to pam_radius_auth.c
(typecasting and debug).

After applying the patch to the vanilla pam_radius-1.3.15, it continues
to work just fine on Linux (Red Hat 7.3), so i guess we broke nothing in
the process. :-)

-- 
Florin Andrei

"You can get excited about just any subject if you study it enough.
It's the deep knowledge that makes a topic interesting." - Larry McVoy
diff -ru pam_radius-1.3.15.old/Makefile pam_radius-1.3.15/Makefile
--- pam_radius-1.3.15.old/Makefile	Mon May  6 07:16:11 2002
+++ pam_radius-1.3.15/Makefile	Wed Jun 26 16:55:20 2002
@@ -16,6 +16,12 @@
 #  If you're not using GCC, then you'll have to change the CFLAGS.
 #
 CFLAGS = -Wall -fPIC
+#
+# On Irix, use this with MIPSPRo C Compiler, and don't forget to export CC=cc
+# gcc does not work yet for pam_radius
+# Also, use gmake instead of make
+# Then copy pam_radius_auth.so to /usr/freeware/lib32/security (PAM dir)
+# CFLAGS =
 
 ######################################################################
 #
@@ -40,6 +46,10 @@
 #
 pam_radius_auth.so: pam_radius_auth.o md5.o
 	ld -Bshareable pam_radius_auth.o md5.o -lpam -o pam_radius_auth.so
+#
+# This is what should work on Irix:
+#pam_radius_auth.so: pam_radius_auth.o md5.o
+#	ld -shared pam_radius_auth.o md5.o -L/usr/freeware/lib32 -lpam -lc -o pam_radius_auth.so
 
 ######################################################################
 #
diff -ru pam_radius-1.3.15.old/md5.c pam_radius-1.3.15/md5.c
--- pam_radius-1.3.15.old/md5.c	Thu Aug 19 06:13:26 1999
+++ pam_radius-1.3.15/md5.c	Wed Jun 26 14:55:41 2002
@@ -40,6 +40,10 @@
 #define HIGHFIRST
 #endif
 
+#ifdef sgi
+#define HIGHFIRST
+#endif
+
 #ifndef HIGHFIRST
 #define byteReverse(buf, len)	/* Nothing */
 #else
diff -ru pam_radius-1.3.15.old/pam_radius_auth.c pam_radius-1.3.15/pam_radius_auth.c
--- pam_radius-1.3.15.old/pam_radius_auth.c	Mon May  6 07:18:34 2002
+++ pam_radius-1.3.15/pam_radius_auth.c	Wed Jun 26 14:48:00 2002
@@ -66,6 +66,8 @@
     va_end(args);
 }
 
+#define DPRINT if (ctrl & PAM_DEBUG_ARG) _pam_log
+
 /* argument parsing */
 static int _pam_parse(int argc, CONST char **argv, radius_conf_t *conf)
 {
@@ -231,12 +233,15 @@
 host2server(radius_server_t *server)
 {
   char *p;
+  int ctrl; ctrl = 0; ctrl++;	/* so I can use DPRINT; warning free */
   
   if ((p = strchr(server->hostname, ':')) != NULL) {
     *(p++) = '\0';		/* split the port off from the host name */
   }
   
-  if ((server->ip.s_addr = get_ipaddr(server->hostname)) == ((UINT4)0)) {
+  if ((server->ip.s_addr = get_ipaddr(server->hostname)) == ((UINT4)0))
+  {
+    DPRINT(LOG_DEBUG, "DEBUG: get_ipaddr(%s) returned 0.\n", server->hostname);
     return PAM_AUTHINFO_UNAVAIL;
   }
 
@@ -257,16 +262,22 @@
       
       if (p) {			/* maybe it's not "radius" */
 	svp = getservbyname (p, "udp");
+	/* quotes allow distinction from above, lest p be radius or radacct */
+	DPRINT(LOG_DEBUG, "DEBUG: getservbyname('%s', udp) returned %d.\n", p, svp);
 	*(--p) = ':';		/* be sure to put the delimiter back */
       } else {
 	if (!server->accounting) {
 	  svp = getservbyname ("radius", "udp");
+	  DPRINT(LOG_DEBUG, "DEBUG: getservbyname(radius, udp) returned %d.\n", svp);
 	} else {
 	  svp = getservbyname ("radacct", "udp");
+	  DPRINT(LOG_DEBUG, "DEBUG: getservbyname(radacct, udp) returned %d.\n", svp);
 	}
       }
       
-      if (svp == (struct servent *) 0) {
+      if (svp == (struct servent *) 0)
+      {
+	/* debugging above... */
 	return PAM_AUTHINFO_UNAVAIL;
       }
       
@@ -358,7 +369,7 @@
   MD5Init(&my_md5);
   memcpy(((char *)request) + len, server->secret, secretlen);
 
-  MD5Update(&my_md5, (char *)request, len + secretlen);
+  MD5Update(&my_md5, (const unsigned char *)request, len + secretlen);
   MD5Final(request->vector, &my_md5);      /* set the final vector */
 }
 
@@ -393,7 +404,7 @@
    * to the secret!
    */
   if (*secret) {
-    MD5Update(&my_md5, secret, strlen(secret));
+    MD5Update(&my_md5, (const unsigned char *)secret, strlen(secret));
   }
 
   MD5Final(calculated, &my_md5);      /* set the final vector */
@@ -470,7 +481,7 @@
   int i;
   int length = strlen(password);
   char hashed[256 + AUTH_PASS_LEN]; /* can't be longer than this */
-  char *vector;
+  unsigned char *vector;
   attribute_t *attr;
 
   if (length > MAXPASS) {	/* shorten the password for now */
@@ -499,18 +510,18 @@
   /* encrypt the password */
   /* password : e[0] = p[0] ^ MD5(secret + vector) */
   MD5Init(&md5_secret);
-  MD5Update(&md5_secret, secret, strlen(secret));
+  MD5Update(&md5_secret, (const unsigned char *)secret, strlen(secret));
   my_md5 = md5_secret;		/* so we won't re-do the hash later */
   MD5Update(&my_md5, vector, AUTH_VECTOR_LEN);
   MD5Final(misc, &my_md5);      /* set the final vector */
-  xor(hashed, misc, AUTH_PASS_LEN);
+  xor((unsigned char *)hashed, misc, AUTH_PASS_LEN);
   
   /* For each step through, e[i] = p[i] ^ MD5(secret + e[i-1]) */
   for (i = 1; i < (length >> 4); i++) {
     my_md5 = md5_secret;	/* grab old value of the hash */
-    MD5Update(&my_md5, &hashed[(i-1) * AUTH_PASS_LEN], AUTH_PASS_LEN);
+    MD5Update(&my_md5, (const unsigned char *)(&hashed[(i-1) * AUTH_PASS_LEN]), AUTH_PASS_LEN);
     MD5Final(misc, &my_md5);      /* set the final vector */
-    xor(&hashed[i * AUTH_PASS_LEN], misc, AUTH_PASS_LEN);
+    xor((unsigned char *)(&hashed[i * AUTH_PASS_LEN]), misc, AUTH_PASS_LEN);
   }
 
   if (type == PW_OLD_PASSWORD) {
@@ -518,7 +529,7 @@
   }
   
   if (!attr) {
-    add_attribute(request, type, hashed, length);
+    add_attribute(request, type, (const unsigned char *)hashed, length);
   } else {
     memcpy(attr->data, hashed, length); /* overwrite the packet */
   }
@@ -675,7 +686,7 @@
     get_random_vector(request->vector);
   }
   
-  add_attribute(request, PW_USER_NAME, (char *) user, strlen(user));
+  add_attribute(request, PW_USER_NAME, (const unsigned char *) user, strlen(user));
 
   /*
    *  Add a password, if given.
@@ -708,9 +719,10 @@
     add_int_attribute(request, PW_NAS_IP_ADDRESS, ipaddr);
   }
 
+
   /* There's always a NAS identifier */
   if (conf->client_id && *conf->client_id) {
-    add_attribute(request, PW_NAS_IDENTIFIER, conf->client_id,
+    add_attribute(request, PW_NAS_IDENTIFIER, (const unsigned char *)conf->client_id,
 		  strlen(conf->client_id));
   }
 
@@ -741,6 +753,7 @@
   radius_server_t *server = conf->server;
   int ok;
   int server_tries;
+  int retval;
 
   /* ************************************************************ */
   /* Now that we're done building the request, we can send it */
@@ -759,9 +772,9 @@
   while (server != NULL) {
 
     /* only look up IP information as necessary */
-    if (host2server(server) != PAM_SUCCESS) {
-      _pam_log(LOG_ERR, "Failed looking up IP address for RADIUS server %s",
-	       server->hostname);
+    if ((retval = host2server(server)) != PAM_SUCCESS) {
+      _pam_log(LOG_ERR, "Failed looking up IP address for RADIUS server %s (errcode=%d)",
+	       server->hostname, retval);
       ok = FALSE;
       goto next;		/* skip to the next server */
     }
@@ -1016,8 +1029,6 @@
 	              , (void *) pret, _int_free );	\
 	return retval; }
 
-#define DPRINT if (ctrl & PAM_DEBUG_ARG) _pam_log
-
 PAM_EXTERN int 
 pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,CONST char **argv)
 {
@@ -1053,7 +1064,7 @@
     return PAM_USER_UNKNOWN;
   }
 
-  DPRINT(LOG_DEBUG, "Got user name %s", user);
+  DPRINT(LOG_DEBUG, "Got User Name %s", user);
 
   /*
    * Get the IP address of the authentication server
@@ -1117,7 +1128,7 @@
   retval = pam_get_item(pamh, PAM_RHOST, (CONST void **) &rhost);
   PAM_FAIL_CHECK;
   if (rhost) {
-    add_attribute(request, PW_CALLING_STATION_ID, rhost, strlen(rhost));
+    add_attribute(request, PW_CALLING_STATION_ID, (const unsigned char *)rhost, strlen(rhost));
   }
 
   DPRINT(LOG_DEBUG, "Sending RADIUS request code %d", request->code);
@@ -1222,7 +1233,7 @@
 		    int status)
 {
   CONST char *user;
-  int ctrl;
+  /* int ctrl; */
   int retval = PAM_AUTH_ERR;
 
   char recv_buffer[4096];
@@ -1231,7 +1242,7 @@
   AUTH_HDR *response = (AUTH_HDR *) recv_buffer;
   radius_conf_t config;
 
-  ctrl = _pam_parse(argc, argv, &config);
+  /* ctrl = */ _pam_parse(argc, argv, &config);
 
   /* grab the user name */
   retval = pam_get_user(pamh, &user, NULL);
@@ -1273,7 +1284,7 @@
   add_int_attribute(request, PW_ACCT_STATUS_TYPE, status);
 
   sprintf(recv_buffer, "%08d", (int) getpid());
-  add_attribute(request, PW_ACCT_SESSION_ID, recv_buffer, strlen(recv_buffer));
+  add_attribute(request, PW_ACCT_SESSION_ID, (const unsigned char *)recv_buffer, strlen(recv_buffer));
 
   add_int_attribute(request, PW_ACCT_AUTHENTIC, PW_AUTH_RADIUS);
 
diff -ru pam_radius-1.3.15.old/pam_radius_auth.h pam_radius-1.3.15/pam_radius_auth.h
--- pam_radius-1.3.15.old/pam_radius_auth.h	Mon Mar 25 18:43:51 2002
+++ pam_radius-1.3.15/pam_radius_auth.h	Tue Jun 25 19:18:32 2002
@@ -88,7 +88,7 @@
 /* Module defines */
 #ifndef BUFFER_SIZE
 #define BUFFER_SIZE      1024
-#endif BUFFER_SIZE
+#endif /* BUFFER_SIZE */
 #define MAXPWNAM 20     /* maximum user name length. Server dependent,
                          * this is the default value
                          */

Reply via email to