*
***********************************************************************/
static char const RCSID[] =
-"$Id: radius.c,v 1.15 2002/09/12 05:41:49 fcusack Exp $";
+"$Id: radius.c,v 1.20 2002/12/24 03:43:35 fcusack Exp $";
#include "pppd.h"
#include "chap.h"
#define BUF_LEN 1024
static char *config_file = NULL;
+static int add_avp(char **);
+static struct avpopt {
+ char *vpstr;
+ struct avpopt *next;
+} *avpopt = NULL;
static option_t Options[] = {
{ "radius-config-file", o_string, &config_file },
+ { "avpair", o_special, add_avp },
{ NULL }
};
SERVER *acctserver; /* Accounting server to use */
int class_len;
char class[MAXCLASSLEN];
+ VALUE_PAIR *avp; /* Additional (user supplied) vp's to send to server */
};
void (*radius_attributes_hook)(VALUE_PAIR *) = NULL;
info("RADIUS plugin initialized.");
}
+/**********************************************************************
+* %FUNCTION: add_avp
+* %ARGUMENTS:
+* argv -- the <attribute=value> pair to add
+* %RETURNS:
+* 1
+* %DESCRIPTION:
+* Adds an av pair to be passed on to the RADIUS server on each request.
+***********************************************************************/
+static int
+add_avp(char **argv)
+{
+ struct avpopt *p = malloc(sizeof(struct avpopt));
+
+ /* Append to a list of vp's for later parsing */
+ p->vpstr = strdup(*argv);
+ p->next = avpopt;
+ avpopt = p;
+
+ return 1;
+}
+
/**********************************************************************
* %FUNCTION: radius_secret_check
* %ARGUMENTS:
VENDOR_NONE);
}
+ /* Add user specified vp's */
+ if (rstate.avp)
+ rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
+
if (rstate.authserver) {
result = rc_auth_using_server(rstate.authserver,
rstate.client_port, send,
break;
}
#endif
+ }
+ if (*remote_number) {
+ rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0,
+ VENDOR_NONE);
}
+ /* Add user specified vp's */
+ if (rstate.avp)
+ rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
+
/*
* make authentication with RADIUS server
*/
{
u_int32_t remote;
int ms_chap2_success = 0;
+#ifdef MPPE
+ int mppe_enc_keys = 0; /* whether or not these were received */
+ int mppe_enc_policy = 0;
+ int mppe_enc_types = 0;
+#endif
/* Send RADIUS attributes to anyone else who might be interested */
if (radius_attributes_hook) {
"RADIUS: bad MS-CHAP-MPPE-Keys attribute");
return -1;
}
+ mppe_enc_keys = 1;
break;
case PW_MS_MPPE_SEND_KEY:
"Send": "Recv");
return -1;
}
+ mppe_enc_keys = 1;
break;
-#endif /* MPPE */
-#if 0
+
case PW_MS_MPPE_ENCRYPTION_POLICY:
+ mppe_enc_policy = vp->lvalue; /* save for later */
+ break;
+
case PW_MS_MPPE_ENCRYPTION_TYPES:
+ mppe_enc_types = vp->lvalue; /* save for later */
+ break;
+
+#endif /* MPPE */
+#if 0
case PW_MS_PRIMARY_DNS_SERVER:
case PW_MS_SECONDARY_DNS_SERVER:
case PW_MS_PRIMARY_NBNS_SERVER:
if (cstate && (cstate->chal_type == CHAP_MICROSOFT_V2) && !ms_chap2_success)
return -1;
+#ifdef MPPE
+ /*
+ * Require both policy and key attributes to indicate a valid key.
+ * Note that if the policy value was '0' we don't set the key!
+ */
+ if (mppe_enc_policy && mppe_enc_keys) {
+ mppe_keys_set = 1;
+ /* Set/modify allowed encryption types. */
+ if (mppe_enc_types)
+ set_mppe_enc_types(mppe_enc_policy, mppe_enc_types);
+ }
+#endif
+
return 0;
}
av_type = htonl(hisaddr);
rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
+ /* Add user specified vp's */
+ if (rstate.avp)
+ rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
+
if (rstate.acctserver) {
result = rc_acct_using_server(rstate.acctserver,
rstate.client_port, send);
av_type = htonl(hisaddr);
rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
+ /* Add user specified vp's */
+ if (rstate.avp)
+ rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
+
if (rstate.acctserver) {
result = rc_acct_using_server(rstate.acctserver,
rstate.client_port, send);
av_type = htonl(hisaddr);
rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
+ /* Add user specified vp's */
+ if (rstate.avp)
+ rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
+
if (rstate.acctserver) {
result = rc_acct_using_server(rstate.acctserver,
rstate.client_port, send);
rc_conf_str("mapfile"));
return -1;
}
+
+ /* Add av pairs saved during option parsing */
+ while (avpopt) {
+ struct avpopt *n = avpopt->next;
+
+ rc_avpair_parse(avpopt->vpstr, &rstate.avp);
+ free(avpopt->vpstr);
+ free(avpopt);
+ avpopt = n;
+ }
return 0;
}