*
***********************************************************************/
static char const RCSID[] =
-"$Id: radius.c,v 1.21 2003/11/25 11:50:10 paulus Exp $";
+"$Id: radius.c,v 1.31 2006/05/22 00:01:40 paulus Exp $";
#include "pppd.h"
#include "chap-new.h"
#include <sys/types.h>
#include <sys/time.h>
#include <string.h>
+#include <netinet/in.h>
+#include <stdlib.h>
#define BUF_LEN 1024
char *vpstr;
struct avpopt *next;
} *avpopt = NULL;
+static bool portnummap = 0;
static option_t Options[] = {
{ "radius-config-file", o_string, &config_file },
{ "avpair", o_special, add_avp },
+ { "map-to-ttyname", o_bool, &portnummap,
+ "Set Radius NAS-Port attribute value via libradiusclient library", OPT_PRIO | 1 },
+ { "map-to-ifname", o_bool, &portnummap,
+ "Set Radius NAS-Port attribute to number as in interface name (Default)", OPT_PRIOSUB | 0 },
{ NULL }
};
struct chap_digest_type *digest,
unsigned char *challenge,
unsigned char *response,
- unsigned char *message, int message_space);
+ char *message, int message_space);
static void radius_ip_up(void *opaque, int arg);
static void radius_ip_down(void *opaque, int arg);
/* Hack... the "port" is the ppp interface number. Should really be
the tty */
- rstate.client_port = get_client_port(ifname);
+ rstate.client_port = get_client_port(portnummap ? devnam : ifname);
av_type = PW_FRAMED;
rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE);
if (*remote_number) {
rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0,
VENDOR_NONE);
- }
+ } else if (ipparam)
+ rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
/* Add user specified vp's */
if (rstate.avp)
radius_chap_verify(char *user, char *ourname, int id,
struct chap_digest_type *digest,
unsigned char *challenge, unsigned char *response,
- unsigned char *message, int message_space)
+ char *message, int message_space)
{
VALUE_PAIR *send, *received;
UINT4 av_type;
/* Put user with potentially realm added in rstate.user */
if (!rstate.done_chap_once) {
make_username_realm(user);
- rstate.client_port = get_client_port (ifname);
+ rstate.client_port = get_client_port (portnummap ? devnam : ifname);
if (radius_pre_auth_hook) {
radius_pre_auth_hook(rstate.user,
&rstate.authserver,
case CHAP_MICROSOFT:
{
/* MS-CHAP-Challenge and MS-CHAP-Response */
- MS_ChapResponse *rmd = (MS_ChapResponse *) response;
u_char *p = cpassword;
if (response_len != MS_CHAP_RESPONSE_LEN)
return 0;
*p++ = id;
/* The idiots use a different field order in RADIUS than PPP */
- memcpy(p, rmd->UseNT, sizeof(rmd->UseNT));
- p += sizeof(rmd->UseNT);
- memcpy(p, rmd->LANManResp, sizeof(rmd->LANManResp));
- p += sizeof(rmd->LANManResp);
- memcpy(p, rmd->NTResp, sizeof(rmd->NTResp));
+ *p++ = response[MS_CHAP_USENT];
+ memcpy(p, response, MS_CHAP_LANMANRESP_LEN + MS_CHAP_NTRESP_LEN);
rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE,
challenge, challenge_len, VENDOR_MICROSOFT);
case CHAP_MICROSOFT_V2:
{
/* MS-CHAP-Challenge and MS-CHAP2-Response */
- MS_Chap2Response *rmd = (MS_Chap2Response *) (response + 1);
u_char *p = cpassword;
if (response_len != MS_CHAP2_RESPONSE_LEN)
return 0;
*p++ = id;
/* The idiots use a different field order in RADIUS than PPP */
- memcpy(p, rmd->Flags, sizeof(rmd->Flags));
- p += sizeof(rmd->Flags);
- memcpy(p, rmd->PeerChallenge, sizeof(rmd->PeerChallenge));
- p += sizeof(rmd->PeerChallenge);
- memcpy(p, rmd->Reserved, sizeof(rmd->Reserved));
- p += sizeof(rmd->Reserved);
- memcpy(p, rmd->NTResp, sizeof(rmd->NTResp));
+ *p++ = response[MS_CHAP2_FLAGS];
+ memcpy(p, response, (MS_CHAP2_PEER_CHAL_LEN + MS_CHAP2_RESERVED_LEN
+ + MS_CHAP2_NTRESP_LEN));
rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE,
challenge, challenge_len, VENDOR_MICROSOFT);
if (*remote_number) {
rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0,
VENDOR_NONE);
- }
+ } else if (ipparam)
+ rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
/* Add user specified vp's */
if (rstate.avp)
req_info);
}
+ strlcpy(message, radius_msg, message_space);
+
if (result == OK_RC) {
if (!rstate.done_chap_once) {
if (radius_setparams(received, radius_msg, req_info, digest,
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);
+ MD5_Init(&Context);
+ MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
+ MD5_Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN);
+ MD5_Final(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);
+ MD5_Init(&Context);
+ MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
+ MD5_Update(&Context, vp->strvalue, 16);
+ MD5_Final(buf, &Context);
for(i = 0; i < 16; i++)
plain[i + 16] ^= buf[i];
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);
+ MD5_Init(&Context);
+ MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
+ MD5_Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN);
+ MD5_Update(&Context, salt, 2);
+ MD5_Final(buf, &Context);
for (i = 0; i < 16; i++)
plain[i] ^= buf[i];
return -1;
}
- MD5Init(&Context);
- MD5Update(&Context, req_info->secret, strlen(req_info->secret));
- MD5Update(&Context, crypt, 16);
- MD5Final(buf, &Context);
+ MD5_Init(&Context);
+ MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
+ MD5_Update(&Context, crypt, 16);
+ MD5_Final(buf, &Context);
plain[16] ^= buf[0]; /* only need the first byte */
if (*remote_number) {
rc_avpair_add(&send, PW_CALLING_STATION_ID,
remote_number, 0, VENDOR_NONE);
- }
+ } else if (ipparam)
+ rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
av_type = PW_RADIUS;
rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE);
- av_type = PW_ASYNC;
+ av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) );
rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE);
hisaddr = ho->hisaddr;
if (*remote_number) {
rc_avpair_add(&send, PW_CALLING_STATION_ID,
remote_number, 0, VENDOR_NONE);
- }
+ } else if (ipparam)
+ rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
- av_type = PW_ASYNC;
+ av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) );
rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE);
+ av_type = PW_NAS_ERROR;
+ switch( status ) {
+ case EXIT_OK:
+ case EXIT_USER_REQUEST:
+ av_type = PW_USER_REQUEST;
+ break;
+
+ case EXIT_HANGUP:
+ case EXIT_PEER_DEAD:
+ case EXIT_CONNECT_FAILED:
+ av_type = PW_LOST_CARRIER;
+ break;
+
+ case EXIT_INIT_FAILED:
+ case EXIT_OPEN_FAILED:
+ case EXIT_LOCK_FAILED:
+ case EXIT_PTYCMD_FAILED:
+ av_type = PW_PORT_ERROR;
+ break;
+
+ case EXIT_PEER_AUTH_FAILED:
+ case EXIT_AUTH_TOPEER_FAILED:
+ case EXIT_NEGOTIATION_FAILED:
+ case EXIT_CNID_AUTH_FAILED:
+ av_type = PW_SERVICE_UNAVAILABLE;
+ break;
+
+ case EXIT_IDLE_TIMEOUT:
+ av_type = PW_ACCT_IDLE_TIMEOUT;
+ break;
+
+ case EXIT_CALLBACK:
+ av_type = PW_CALLBACK;
+ break;
+
+ case EXIT_CONNECT_TIME:
+ av_type = PW_ACCT_SESSION_TIMEOUT;
+ break;
+
+#ifdef MAXOCTETS
+ case EXIT_TRAFFIC_LIMIT:
+ av_type = PW_NAS_REQUEST;
+ break;
+#endif
+
+ default:
+ av_type = PW_NAS_ERROR;
+ break;
+ }
+ rc_avpair_add(&send, PW_ACCT_TERMINATE_CAUSE, &av_type, 0, VENDOR_NONE);
+
hisaddr = ho->hisaddr;
av_type = htonl(hisaddr);
rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
if (*remote_number) {
rc_avpair_add(&send, PW_CALLING_STATION_ID,
remote_number, 0, VENDOR_NONE);
- }
+ } else if (ipparam)
+ rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
- av_type = PW_ASYNC;
+ av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) );
rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE);
hisaddr = ho->hisaddr;