Added RADIUS support for MPPE (patch from Frank Cusack)

This commit is contained in:
David F. Skoll 2002-04-02 14:09:35 +00:00
parent dbab7400ab
commit 487bb16936
8 changed files with 306 additions and 84 deletions

View File

@ -40,7 +40,14 @@
#ifndef __MD5_INCLUDE__
/* typedef a 32-bit type */
#ifdef _LP64
typedef unsigned int UINT4;
typedef int INT4;
#else
typedef unsigned long UINT4;
typedef long INT4;
#endif
#define _UINT4_T
/* Data structure for MD5 (Message-Digest) computation */
typedef struct {

View File

@ -5,14 +5,19 @@
MANDIR=/usr/man
PLUGIN=radius.so radattr.so
CFLAGS=-I../.. -Iradiusclient/include -O2
CFLAGS=-I../.. -I../../../include -Iradiusclient/include -O2
# Uncomment the next line to include support for Microsoft's
# MS-CHAP authentication protocol.
CHAPMS=y
# Uncomment the next line to include support for MPPE.
MPPE=y
ifdef CHAPMS
CFLAGS += -DCHAPMS=1
ifdef MPPE
CFLAGS += -DMPPE=1
endif
endif
all: $(PLUGIN)

View File

@ -16,17 +16,23 @@
* Copyright (C) 1995,1996,1997,1998 Lars Fenneberg <lf@elemental.net>
* Copyright (C) 2002 Roaring Penguin Software Inc.
*
* MPPE support is by Ralf Hofmann, <ralf.hofmann@elvido.net>, with
* modification from Frank Cusack, <frank@google.com>.
*
* This plugin may be distributed according to the terms of the GNU
* General Public License, version 2 or (at your option) any later version.
*
***********************************************************************/
static char const RCSID[] =
"$Id: radius.c,v 1.8 2002/04/02 13:55:00 dfs Exp $";
"$Id: radius.c,v 1.9 2002/04/02 14:09:34 dfs Exp $";
#include "pppd.h"
#include "chap.h"
#ifdef CHAPMS
#include "chap_ms.h"
#ifdef MPPE
#include "md5.h"
#endif
#endif
#include "radiusclient.h"
#include "fsm.h"
@ -58,11 +64,17 @@ static int radius_chap_auth(char *user,
static void radius_ip_up(void *opaque, int arg);
static void radius_ip_down(void *opaque, int arg);
static void make_username_realm(char *user);
static int radius_setparams(chap_state *cstate, VALUE_PAIR *vp, char *msg);
static int radius_setparams(chap_state *cstate, VALUE_PAIR *vp, char *msg,
REQUEST_INFO *req_info);
static void radius_choose_ip(u_int32_t *addrp);
static int radius_init(char *msg);
static int get_client_port(char *ifname);
static int radius_allowed_address(u_int32_t addr);
#ifdef MPPE
static int radius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info,
chap_state *);
static int radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info);
#endif
#ifndef MAXSESSIONID
#define MAXSESSIONID 32
@ -227,13 +239,13 @@ radius_pap_auth(char *user,
if (rstate.authserver) {
result = rc_auth_using_server(rstate.authserver,
rstate.client_port, send,
&received, radius_msg);
&received, radius_msg, NULL);
} else {
result = rc_auth(rstate.client_port, send, &received, radius_msg);
result = rc_auth(rstate.client_port, send, &received, radius_msg, NULL);
}
if (result == OK_RC) {
if (radius_setparams(NULL, received, radius_msg) < 0) {
if (radius_setparams(NULL, received, radius_msg, NULL) < 0) {
result = ERROR_RC;
}
}
@ -255,7 +267,7 @@ radius_pap_auth(char *user,
* %RETURNS:
* CHAP_SUCCESS if we can authenticate, CHAP_FAILURE if we cannot.
* %DESCRIPTION:
* Performs CHAP, MS-CHAP and MS-CHAPv2 authentication using RADIUS
* Performs CHAP, MS-CHAP and MS-CHAPv2 authentication using RADIUS.
***********************************************************************/
static int
radius_chap_auth(char *user,
@ -268,6 +280,13 @@ radius_chap_auth(char *user,
static char radius_msg[BUF_LEN];
int result;
u_char cpassword[MAX_RESPONSE_LENGTH + 1];
#ifdef MPPE
/* Need the RADIUS secret and Request Authenticator to decode MPPE */
REQUEST_INFO request_info, *req_info = &request_info;
#else
REQUEST_INFO *req_info = NULL;
#endif
radius_msg[0] = 0;
if (radius_init(radius_msg) < 0) {
@ -377,14 +396,15 @@ radius_chap_auth(char *user,
if (rstate.authserver) {
result = rc_auth_using_server(rstate.authserver,
rstate.client_port, send,
&received, radius_msg);
&received, radius_msg, req_info);
} else {
result = rc_auth(rstate.client_port, send, &received, radius_msg);
result = rc_auth(rstate.client_port, send, &received, radius_msg,
req_info);
}
if (result == OK_RC) {
if (!rstate.done_chap_once) {
if (radius_setparams(cstate, received, radius_msg) < 0) {
if (radius_setparams(cstate, received, radius_msg, req_info) < 0) {
error("%s", radius_msg);
result = ERROR_RC;
} else {
@ -438,11 +458,11 @@ make_username_realm(char *user)
* %RETURNS:
* >= 0 on success; -1 on failure
* %DESCRIPTION:
* Parses attributes sent by RADIUS server and sets them in pppd. Currently,
* used only to set IP address and MS-CHAPv2 Authenticator Response.
* Parses attributes sent by RADIUS server and sets them in pppd.
***********************************************************************/
static int
radius_setparams(chap_state *cstate, VALUE_PAIR *vp, char *msg)
radius_setparams(chap_state *cstate, VALUE_PAIR *vp, char *msg,
REQUEST_INFO *req_info)
{
u_int32_t remote;
int ms_chap2_success = 0;
@ -458,57 +478,96 @@ radius_setparams(chap_state *cstate, VALUE_PAIR *vp, char *msg)
*/
while (vp) {
if ((vp->attribute == PW_SERVICE_TYPE) &&
(vp->vendorcode == VENDOR_NONE)) {
/* check for service type */
/* if not FRAMED then exit */
if (vp->lvalue != PW_FRAMED) {
slprintf(msg, BUF_LEN, "RADIUS: wrong service type %ld for %s",
vp->lvalue, rstate.user);
return -1;
}
} else if ((vp->attribute == PW_FRAMED_PROTOCOL) &&
(vp->vendorcode == VENDOR_NONE)) {
/* check for framed protocol type */
/* if not PPP then also exit */
if (vp->lvalue != PW_PPP) {
slprintf(msg, BUF_LEN, "RADIUS: wrong framed protocol %ld for %s",
vp->lvalue, rstate.user);
return -1;
}
} else if ((vp->attribute == PW_SESSION_TIMEOUT) &&
(vp->vendorcode == VENDOR_NONE)) {
/* Session timeout */
maxconnect = vp->lvalue;
} else if ((vp->attribute == PW_FRAMED_IP_ADDRESS) &&
(vp->vendorcode == VENDOR_NONE)) {
/* seting up remote IP addresses */
remote = vp->lvalue;
if (remote == 0xffffffff) {
/* 0xffffffff means user should be allowed to select one */
rstate.any_ip_addr_ok = 1;
} else if (remote != 0xfffffffe) {
/* 0xfffffffe means NAS should select an ip address */
remote = htonl(vp->lvalue);
if (bad_ip_adrs (remote)) {
slprintf(msg, BUF_LEN, "RADIUS: bad remote IP address %I for %s",
remote, rstate.user);
if (vp->vendorcode == VENDOR_NONE) {
switch (vp->attribute) {
case PW_SERVICE_TYPE:
/* check for service type */
/* if not FRAMED then exit */
if (vp->lvalue != PW_FRAMED) {
slprintf(msg, BUF_LEN, "RADIUS: wrong service type %ld for %s",
vp->lvalue, rstate.user);
return -1;
}
rstate.choose_ip = 1;
rstate.ip_addr = remote;
break;
case PW_FRAMED_PROTOCOL:
/* check for framed protocol type */
/* if not PPP then also exit */
if (vp->lvalue != PW_PPP) {
slprintf(msg, BUF_LEN, "RADIUS: wrong framed protocol %ld for %s",
vp->lvalue, rstate.user);
return -1;
}
break;
case PW_SESSION_TIMEOUT:
/* Session timeout */
maxconnect = vp->lvalue;
break;
case PW_FRAMED_IP_ADDRESS:
/* seting up remote IP addresses */
remote = vp->lvalue;
if (remote == 0xffffffff) {
/* 0xffffffff means user should be allowed to select one */
rstate.any_ip_addr_ok = 1;
} else if (remote != 0xfffffffe) {
/* 0xfffffffe means NAS should select an ip address */
remote = htonl(vp->lvalue);
if (bad_ip_adrs (remote)) {
slprintf(msg, BUF_LEN, "RADIUS: bad remote IP address %I for %s",
remote, rstate.user);
return -1;
}
rstate.choose_ip = 1;
rstate.ip_addr = remote;
}
break;
}
#ifdef CHAPMS
} else if ((vp->attribute == PW_MS_CHAP2_SUCCESS) &&
(vp->vendorcode == VENDOR_MICROSOFT)) {
if ((vp->lvalue != 43) || strncmp(vp->strvalue + 1, "S=", 2)) {
slprintf(msg, BUF_LEN, "RADIUS: bad MS-CHAP2-Success packet");
return -1;
} else if (vp->vendorcode == VENDOR_MICROSOFT) {
switch (vp->attribute) {
case PW_MS_CHAP2_SUCCESS:
if ((vp->lvalue != 43) || strncmp(vp->strvalue + 1, "S=", 2)) {
slprintf(msg,BUF_LEN,"RADIUS: bad MS-CHAP2-Success packet");
return -1;
}
memcpy(cstate->saresponse, vp->strvalue + 3,
MS_AUTH_RESPONSE_LENGTH);
cstate->saresponse[MS_AUTH_RESPONSE_LENGTH] = '\0';
ms_chap2_success = 1;
break;
#ifdef MPPE
case PW_MS_CHAP_MPPE_KEYS:
if (radius_setmppekeys(vp, req_info, cstate) < 0) {
slprintf(msg, BUF_LEN,
"RADIUS: bad MS-CHAP-MPPE-Keys attribute");
return -1;
}
break;
case PW_MS_MPPE_SEND_KEY:
case PW_MS_MPPE_RECV_KEY:
if (radius_setmppekeys2(vp, req_info) < 0) {
slprintf(msg, BUF_LEN,
"RADIUS: bad MS-MPPE-%s-Key attribute",
(vp->attribute == PW_MS_MPPE_SEND_KEY)?
"Send": "Recv");
return -1;
}
break;
#endif /* MPPE */
#if 0
case PW_MS_MPPE_ENCRYPTION_POLICY:
case PW_MS_MPPE_ENCRYPTION_TYPES:
case PW_MS_PRIMARY_DNS_SERVER:
case PW_MS_SECONDARY_DNS_SERVER:
case PW_MS_PRIMARY_NBNS_SERVER:
case PW_MS_SECONDARY_NBNS_SERVER:
break;
#endif
}
memcpy(cstate->saresponse, vp->strvalue + 3,
MS_AUTH_RESPONSE_LENGTH);
cstate->saresponse[MS_AUTH_RESPONSE_LENGTH] = '\0';
ms_chap2_success = 1;
#endif /* CHAPMS */
}
vp = vp->next;
@ -521,6 +580,130 @@ radius_setparams(chap_state *cstate, VALUE_PAIR *vp, char *msg)
return 0;
}
#ifdef MPPE
/**********************************************************************
* %FUNCTION: radius_setmppekeys
* %ARGUMENTS:
* vp -- value pair holding MS-CHAP-MPPE-KEYS attribute
* req_info -- radius request information used for encryption
* cstate -- chap_state structure for challenge info
* %RETURNS:
* >= 0 on success; -1 on failure
* %DESCRIPTION:
* Decrypt the "key" provided by the RADIUS server for MPPE encryption.
* See RFC 2548.
***********************************************************************/
static int
radius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info, chap_state *cstate)
{
int i;
MD5_CTX Context;
u_char plain[32];
u_char buf[16];
if (vp->lvalue != 32) {
error("RADIUS: Incorrect attribute length (%d) for MS-CHAP-MPPE-Keys",
vp->lvalue);
return -1;
}
memcpy(plain, vp->strvalue, sizeof(plain));
MD5Init(&Context);
MD5Update(&Context, req_info->secret, strlen(req_info->secret));
MD5Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN);
MD5Final(buf, &Context);
for (i = 0; i < 16; i++)
plain[i] ^= buf[i];
MD5Init(&Context);
MD5Update(&Context, req_info->secret, strlen(req_info->secret));
MD5Update(&Context, vp->strvalue, 16);
MD5Final(buf, &Context);
for(i = 0; i < 16; i++)
plain[i + 16] ^= buf[i];
/*
* Annoying. The "key" returned is just the NTPasswordHashHash, which
* the NAS (us) doesn't need; we only need the start key. So we have
* to generate the start key, sigh. NB: We do not support the LM-Key.
*/
mppe_set_keys(cstate->challenge, &plain[8]);
return 0;
}
/**********************************************************************
* %FUNCTION: radius_setmppekeys2
* %ARGUMENTS:
* vp -- value pair holding MS-MPPE-SEND-KEY or MS-MPPE-RECV-KEY attribute
* req_info -- radius request information used for encryption
* %RETURNS:
* >= 0 on success; -1 on failure
* %DESCRIPTION:
* Decrypt the key provided by the RADIUS server for MPPE encryption.
* See RFC 2548.
***********************************************************************/
static int
radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info)
{
int i;
MD5_CTX Context;
u_char *salt = vp->strvalue;
u_char *crypt = vp->strvalue + 2;
u_char plain[32];
u_char buf[MD5_SIGNATURE_SIZE];
char *type = "Send";
if (vp->attribute == PW_MS_MPPE_RECV_KEY)
type = "Recv";
if (vp->lvalue != 34) {
error("RADIUS: Incorrect attribute length (%d) for MS-MPPE-%s-Key",
vp->lvalue, type);
return -1;
}
if ((salt[0] & 0x80) == 0) {
error("RADIUS: Illegal salt value for MS-MPPE-%s-Key attribute", type);
return -1;
}
memcpy(plain, crypt, 32);
MD5Init(&Context);
MD5Update(&Context, req_info->secret, strlen(req_info->secret));
MD5Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN);
MD5Update(&Context, salt, 2);
MD5Final(buf, &Context);
for (i = 0; i < 16; i++)
plain[i] ^= buf[i];
if (plain[0] != sizeof(mppe_send_key) /* 16 */) {
error("RADIUS: Incorrect key length (%d) for MS-MPPE-%s-Key attribute",
(int) plain[0], type);
return -1;
}
MD5Init(&Context);
MD5Update(&Context, req_info->secret, strlen(req_info->secret));
MD5Update(&Context, crypt, 16);
MD5Final(buf, &Context);
plain[16] ^= buf[0]; /* only need the first byte */
if (vp->attribute == PW_MS_MPPE_SEND_KEY)
memcpy(mppe_send_key, plain + 1, 16);
else
memcpy(mppe_recv_key, plain + 1, 16);
return 0;
}
#endif /* MPPE */
/**********************************************************************
* %FUNCTION: radius_acct_start
* %ARGUMENTS:

View File

@ -1,5 +1,5 @@
/*
* $Id: radiusclient.h,v 1.5 2002/03/05 15:14:06 dfs Exp $
* $Id: radiusclient.h,v 1.6 2002/04/02 14:09:34 dfs Exp $
*
* Copyright (C) 1995,1996,1997,1998 Lars Fenneberg
*
@ -38,8 +38,15 @@
# define __P(protos) ()
#endif
#ifndef _UINT4_T
#ifdef _LP64
typedef unsigned int UINT4;
typedef int INT4;
#else
typedef unsigned long UINT4;
typedef long INT4;
typedef long INT4;
#endif
#endif
#define AUTH_VECTOR_LEN 16
#define AUTH_PASS_LEN (3 * 16) /* multiple of 16 */
@ -159,6 +166,12 @@ typedef struct pw_auth_hdr
#define PW_MS_CHAP_RESPONSE 1 /* string */
#define PW_MS_CHAP2_RESPONSE 25 /* string */
#define PW_MS_CHAP2_SUCCESS 26 /* string */
#define PW_MS_MPPE_ENCRYPTION_POLICY 7 /* string */
#define PW_MS_MPPE_ENCRYPTION_TYPE 8 /* string */
#define PW_MS_MPPE_ENCRYPTION_TYPES PW_MS_MPPE_ENCRYPTION_TYPE
#define PW_MS_CHAP_MPPE_KEYS 12 /* string */
#define PW_MS_MPPE_SEND_KEY 16 /* string */
#define PW_MS_MPPE_RECV_KEY 17 /* string */
/* Accounting */
@ -319,7 +332,7 @@ typedef struct value_pair
int vendorcode;
int type;
UINT4 lvalue;
char strvalue[AUTH_STRING_LEN + 1];
u_char strvalue[AUTH_STRING_LEN + 1];
struct value_pair *next;
} VALUE_PAIR;
@ -345,6 +358,12 @@ typedef struct send_data /* Used to pass information to sendserver() function */
VALUE_PAIR *receive_pairs; /* Where to place received a/v pairs */
} SEND_DATA;
typedef struct request_info
{
char secret[MAX_SECRET_LENGTH + 1];
u_char request_vector[AUTH_VECTOR_LEN];
} REQUEST_INFO;
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
@ -385,8 +404,9 @@ VALUE_PAIR *rc_avpair_readin __P((FILE *));
void rc_buildreq __P((SEND_DATA *, int, char *, unsigned short, int, int));
unsigned char rc_get_seqnbr __P((void));
int rc_auth __P((UINT4, VALUE_PAIR *, VALUE_PAIR **, char *));
int rc_auth_using_server __P((SERVER *, UINT4, VALUE_PAIR *, VALUE_PAIR **, char *));
int rc_auth __P((UINT4, VALUE_PAIR *, VALUE_PAIR **, char *, REQUEST_INFO *));
int rc_auth_using_server __P((SERVER *, UINT4, VALUE_PAIR *, VALUE_PAIR **,
char *, REQUEST_INFO *));
int rc_auth_proxy __P((VALUE_PAIR *, VALUE_PAIR **, char *));
int rc_acct __P((UINT4, VALUE_PAIR *));
int rc_acct_using_server __P((SERVER *, UINT4, VALUE_PAIR *));
@ -433,7 +453,7 @@ void rc_log __P((int, const char *, ...));
/* sendserver.c */
int rc_send_server __P((SEND_DATA *, char *));
int rc_send_server __P((SEND_DATA *, char *, REQUEST_INFO *));
/* util.c */

View File

@ -1,5 +1,5 @@
/*
* $Id: buildreq.c,v 1.2 2002/03/01 14:39:19 dfs Exp $
* $Id: buildreq.c,v 1.3 2002/04/02 14:09:35 dfs Exp $
*
* Copyright (C) 1995,1997 Lars Fenneberg
*
@ -120,14 +120,15 @@ unsigned char rc_get_seqnbr(void)
*/
int rc_auth(UINT4 client_port, VALUE_PAIR *send, VALUE_PAIR **received,
char *msg)
char *msg, REQUEST_INFO *info)
{
SERVER *authserver = rc_conf_srv("authserver");
if (!authserver) {
return (ERROR_RC);
}
return rc_auth_using_server(authserver, client_port, send, received, msg);
return rc_auth_using_server(authserver, client_port, send, received,
msg, info);
}
/*
@ -146,7 +147,7 @@ int rc_auth_using_server(SERVER *authserver,
UINT4 client_port,
VALUE_PAIR *send,
VALUE_PAIR **received,
char *msg)
char *msg, REQUEST_INFO *info)
{
SEND_DATA data;
UINT4 client_id;
@ -186,7 +187,7 @@ int rc_auth_using_server(SERVER *authserver,
rc_buildreq(&data, PW_ACCESS_REQUEST, authserver->name[i],
authserver->port[i], timeout, retries);
result = rc_send_server (&data, msg);
result = rc_send_server (&data, msg, info);
}
*received = data.receive_pairs;
@ -230,7 +231,7 @@ int rc_auth_proxy(VALUE_PAIR *send, VALUE_PAIR **received, char *msg)
rc_buildreq(&data, PW_ACCESS_REQUEST, authserver->name[i],
authserver->port[i], timeout, retries);
result = rc_send_server (&data, msg);
result = rc_send_server (&data, msg, NULL);
}
*received = data.receive_pairs;
@ -306,7 +307,7 @@ int rc_acct_using_server(SERVER *acctserver,
dtime = time(NULL) - start_time;
rc_avpair_assign(adt_vp, &dtime, 0);
result = rc_send_server (&data, msg);
result = rc_send_server (&data, msg, NULL);
}
rc_avpair_free(data.receive_pairs);
@ -363,7 +364,7 @@ int rc_acct_proxy(VALUE_PAIR *send)
rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i],
acctserver->port[i], timeout, retries);
result = rc_send_server (&data, msg);
result = rc_send_server (&data, msg, NULL);
}
rc_avpair_free(data.receive_pairs);
@ -406,7 +407,7 @@ int rc_check(char *host, unsigned short port, char *msg)
rc_avpair_add(&(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, VENDOR_NONE);
rc_buildreq(&data, PW_STATUS_SERVER, host, port, timeout, retries);
result = rc_send_server (&data, msg);
result = rc_send_server (&data, msg, NULL);
rc_avpair_free(data.receive_pairs);

View File

@ -1,5 +1,5 @@
/*
* $Id: sendserver.c,v 1.3 2002/03/05 15:36:17 dfs Exp $
* $Id: sendserver.c,v 1.4 2002/04/02 14:09:35 dfs Exp $
*
* Copyright (C) 1995,1996,1997 Lars Fenneberg
*
@ -190,7 +190,7 @@ static int rc_pack_list (VALUE_PAIR *vp, char *secret, AUTH_HDR *auth)
*
*/
int rc_send_server (SEND_DATA *data, char *msg)
int rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info)
{
int sockfd;
struct sockaddr salocal;
@ -279,7 +279,7 @@ int rc_send_server (SEND_DATA *data, char *msg)
else
{
rc_random_vector (vector);
memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
memcpy (auth->vector, vector, AUTH_VECTOR_LEN);
total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;
@ -348,6 +348,12 @@ int rc_send_server (SEND_DATA *data, char *msg)
data->receive_pairs = rc_avpair_gen(recv_auth);
close (sockfd);
if (info)
{
memcpy(info->secret, secret, sizeof(info->secret));
memcpy(info->request_vector, vector,
sizeof(info->request_vector));
}
memset (secret, '\0', sizeof (secret));
if (result != OK_RC) return (result);
@ -388,8 +394,8 @@ int rc_send_server (SEND_DATA *data, char *msg)
*
*/
static int rc_check_reply (AUTH_HDR *auth, int bufferlen, char *secret, unsigned char *vector,\
unsigned char seq_nbr)
static int rc_check_reply (AUTH_HDR *auth, int bufferlen, char *secret,
unsigned char *vector, unsigned char seq_nbr)
{
int secretlen;
int totallen;

View File

@ -1,5 +1,5 @@
/*
* $Id: radexample.c,v 1.1 2002/01/22 16:03:04 dfs Exp $
* $Id: radexample.c,v 1.2 2002/04/02 14:09:35 dfs Exp $
*
* Copyright (C) 1995,1996,1997 Lars Fenneberg
*
@ -11,7 +11,7 @@
static char rcsid[] =
"$Id: radexample.c,v 1.1 2002/01/22 16:03:04 dfs Exp $";
"$Id: radexample.c,v 1.2 2002/04/02 14:09:35 dfs Exp $";
#include <config.h>
#include <includes.h>
@ -87,7 +87,7 @@ main (int argc, char **argv)
if (rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0, VENDOR_NONE) == NULL)
return (ERROR_RC);
result = rc_auth(0, send, &received, msg);
result = rc_auth(0, send, &received, msg, NULL);
if (result == OK_RC)
{

View File

@ -1,5 +1,5 @@
/*
* $Id: radius.c,v 1.1 2002/01/22 16:03:04 dfs Exp $
* $Id: radius.c,v 1.2 2002/04/02 14:09:35 dfs Exp $
*
* Copyright (C) 1996 Lars Fenneberg
*
@ -117,7 +117,7 @@ LFUNC auth_radius(UINT4 client_port, char *username, char *passwd)
if (rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0, VENDOR_NONE) == NULL)
return (LFUNC) NULL;
result = rc_auth(client_port, send, &received, msg);
result = rc_auth(client_port, send, &received, msg, NULL);
if (result == OK_RC)
{