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
*/