*
***********************************************************************/
static char const RCSID[] =
-"$Id: radius.c,v 1.23 2004/03/26 13:27:17 kad Exp $";
+"$Id: radius.c,v 1.32 2008/05/26 09:18:08 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
#define MD5_HASH_SIZE 16
+#define MSDNS 1
+
static char *config_file = NULL;
static int add_avp(char **);
static struct avpopt {
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);
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;
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;
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,
int mppe_enc_policy = 0;
int mppe_enc_types = 0;
#endif
+#ifdef MSDNS
+ ipcp_options *wo = &ipcp_wantoptions[0];
+ ipcp_options *ao = &ipcp_allowoptions[0];
+ int got_msdns_1 = 0;
+ int got_msdns_2 = 0;
+ int got_wins_1 = 0;
+ int got_wins_2 = 0;
+#endif
/* Send RADIUS attributes to anyone else who might be interested */
if (radius_attributes_hook) {
/* Session timeout */
maxconnect = vp->lvalue;
break;
+ case PW_FILTER_ID:
+ /* packet filter, will be handled via ip-(up|down) script */
+ script_setenv("RADIUS_FILTER_ID", vp->strvalue, 1);
+ break;
+ case PW_FRAMED_ROUTE:
+ /* route, will be handled via ip-(up|down) script */
+ script_setenv("RADIUS_FRAMED_ROUTE", vp->strvalue, 1);
+ break;
+ case PW_IDLE_TIMEOUT:
+ /* idle parameter */
+ idle_time_limit = vp->lvalue;
+ break;
#ifdef MAXOCTETS
case PW_SESSION_OCTETS_LIMIT:
/* Session traffic limit */
rstate.ip_addr = remote;
}
break;
+ case PW_NAS_IP_ADDRESS:
+ wo->ouraddr = htonl(vp->lvalue);
+ break;
case PW_CLASS:
/* Save Class attribute to pass it in accounting request */
if (vp->lvalue <= MAXCLASSLEN) {
}
-#ifdef CHAPMS
} else if (vp->vendorcode == VENDOR_MICROSOFT) {
+#ifdef CHAPMS
switch (vp->attribute) {
case PW_MS_CHAP2_SUCCESS:
if ((vp->lvalue != 43) || strncmp(vp->strvalue + 1, "S=", 2)) {
break;
#endif /* MPPE */
-#if 0
+#ifdef MSDNS
case PW_MS_PRIMARY_DNS_SERVER:
+ ao->dnsaddr[0] = htonl(vp->lvalue);
+ got_msdns_1 = 1;
+ if (!got_msdns_2)
+ ao->dnsaddr[1] = ao->dnsaddr[0];
+ break;
case PW_MS_SECONDARY_DNS_SERVER:
+ ao->dnsaddr[1] = htonl(vp->lvalue);
+ got_msdns_2 = 1;
+ if (!got_msdns_1)
+ ao->dnsaddr[0] = ao->dnsaddr[1];
+ break;
case PW_MS_PRIMARY_NBNS_SERVER:
+ ao->winsaddr[0] = htonl(vp->lvalue);
+ got_wins_1 = 1;
+ if (!got_wins_2)
+ ao->winsaddr[1] = ao->winsaddr[0];
+ break;
case PW_MS_SECONDARY_NBNS_SERVER:
+ ao->winsaddr[1] = htonl(vp->lvalue);
+ got_wins_2 = 1;
+ if (!got_wins_1)
+ ao->winsaddr[0] = ao->winsaddr[1];
break;
-#endif
+#endif /* MSDNS */
}
#endif /* CHAPMS */
}
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 = using_pty ? PW_VIRTUAL : 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;
return;
}
+ if (rstate.acct_interim_interval)
+ UNTIMEOUT(radius_acct_interim, NULL);
+
rstate.accounting_started = 0;
rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id,
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 = using_pty ? PW_VIRTUAL : 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;
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;
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 = using_pty ? PW_VIRTUAL : 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;