18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/***********************************************************************
28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*
38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* radius.c
48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*
58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* RADIUS plugin for pppd.  Performs PAP, CHAP, MS-CHAP, MS-CHAPv2
68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* authentication using RADIUS.
78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*
88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Copyright (C) 2002 Roaring Penguin Software Inc.
98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*
108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Based on a patch for ipppd, which is:
118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*    Copyright (C) 1996, Matjaz Godec <gody@elgo.si>
128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*    Copyright (C) 1996, Lars Fenneberg <in5y050@public.uni-hamburg.de>
138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*    Copyright (C) 1997, Miguel A.L. Paraz <map@iphil.net>
148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*
158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Uses radiusclient library, which is:
168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*    Copyright (C) 1995,1996,1997,1998 Lars Fenneberg <lf@elemental.net>
178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*    Copyright (C) 2002 Roaring Penguin Software Inc.
188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*
198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* MPPE support is by Ralf Hofmann, <ralf.hofmann@elvido.net>, with
208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* modification from Frank Cusack, <frank@google.com>.
218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*
228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* This plugin may be distributed according to the terms of the GNU
238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* General Public License, version 2 or (at your option) any later version.
248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*
258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char const RCSID[] =
271286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley"$Id: radius.c,v 1.32 2008/05/26 09:18:08 paulus Exp $";
288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h"
308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "chap-new.h"
318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef CHAPMS
328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "chap_ms.h"
338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "md5.h"
358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "radiusclient.h"
388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "fsm.h"
398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "ipcp.h"
408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <syslog.h>
418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/types.h>
428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <sys/time.h>
438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h>
448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <netinet/in.h>
458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h>
468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define BUF_LEN 1024
488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MD5_HASH_SIZE	16
508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
511286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley#define MSDNS 1
521286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley
538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char *config_file = NULL;
548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int add_avp(char **);
558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic struct avpopt {
568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *vpstr;
578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct avpopt *next;
588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} *avpopt = NULL;
598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic bool portnummap = 0;
608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic option_t Options[] = {
628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "radius-config-file", o_string, &config_file },
638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "avpair", o_special, add_avp },
648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "map-to-ttyname", o_bool, &portnummap,
658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	"Set Radius NAS-Port attribute value via libradiusclient library", OPT_PRIO | 1 },
668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { "map-to-ifname", o_bool, &portnummap,
678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	"Set Radius NAS-Port attribute to number as in interface name (Default)", OPT_PRIOSUB | 0 },
688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    { NULL }
698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int radius_secret_check(void);
728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int radius_pap_auth(char *user,
738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   char *passwd,
748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   char **msgp,
758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   struct wordlist **paddrs,
768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			   struct wordlist **popts);
778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int radius_chap_verify(char *user, char *ourname, int id,
788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			      struct chap_digest_type *digest,
798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			      unsigned char *challenge,
808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			      unsigned char *response,
818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			      char *message, int message_space);
828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void radius_ip_up(void *opaque, int arg);
848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void radius_ip_down(void *opaque, int arg);
858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void make_username_realm(char *user);
868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int radius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info,
878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    struct chap_digest_type *digest,
888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    unsigned char *challenge,
898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			    char *message, int message_space);
908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void radius_choose_ip(u_int32_t *addrp);
918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int radius_init(char *msg);
928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int get_client_port(char *ifname);
938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int radius_allowed_address(u_int32_t addr);
948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void radius_acct_interim(void *);
958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int radius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info,
978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			      unsigned char *);
988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info);
998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef MAXSESSIONID
1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MAXSESSIONID 32
1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifndef MAXCLASSLEN
1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#define MAXCLASSLEN 500
1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstruct radius_state {
1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int accounting_started;
1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int initialized;
1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int client_port;
1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int choose_ip;
1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int any_ip_addr_ok;
1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int done_chap_once;
1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t ip_addr;
1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char user[MAXNAMELEN];
1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char config_file[MAXPATHLEN];
1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char session_id[MAXSESSIONID + 1];
1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    time_t start_time;
1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int acct_interim_interval;
1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    SERVER *authserver;		/* Authentication server to use */
1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    SERVER *acctserver;		/* Accounting server to use */
1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int class_len;
1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char class[MAXCLASSLEN];
1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    VALUE_PAIR *avp;	/* Additional (user supplied) vp's to send to server */
1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project};
1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid (*radius_attributes_hook)(VALUE_PAIR *) = NULL;
1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* The pre_auth_hook MAY set authserver and acctserver if it wants.
1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project   In that case, they override the values in the radiusclient.conf file */
1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid (*radius_pre_auth_hook)(char const *user,
1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			     SERVER **authserver,
1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			     SERVER **acctserver) = NULL;
1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic struct radius_state rstate;
1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar pppd_version[] = VERSION;
1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: plugin_init
1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  None
1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Nothing
1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Initializes RADIUS plugin.
1498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
1508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid
1518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectplugin_init(void)
1528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
1538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pap_check_hook = radius_secret_check;
1548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    pap_auth_hook = radius_pap_auth;
1558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    chap_check_hook = radius_secret_check;
1578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    chap_verify_hook = radius_chap_verify;
1588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ip_choose_hook = radius_choose_ip;
1608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    allowed_address_hook = radius_allowed_address;
1618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    add_notifier(&ip_up_notifier, radius_ip_up, NULL);
1638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    add_notifier(&ip_down_notifier, radius_ip_down, NULL);
1648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memset(&rstate, 0, sizeof(rstate));
1668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strlcpy(rstate.config_file, "/etc/radiusclient/radiusclient.conf",
1688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    sizeof(rstate.config_file));
1698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    add_options(Options);
1718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    info("RADIUS plugin initialized.");
1738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
1768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: add_avp
1778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
1788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  argv -- the <attribute=value> pair to add
1798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
1808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  1
1818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
1828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Adds an av pair to be passed on to the RADIUS server on each request.
1838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
1848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
1858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectadd_avp(char **argv)
1868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
1878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    struct avpopt *p = malloc(sizeof(struct avpopt));
1888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Append to a list of vp's for later parsing */
1908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p->vpstr = strdup(*argv);
1918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    p->next = avpopt;
1928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    avpopt = p;
1938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
1958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
1978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
1988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_secret_check
1998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
2008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  None
2018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
2028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  1 -- we are ALWAYS willing to supply a secret. :-)
2038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
2048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Tells pppd that we will try to authenticate the peer, and not to
2058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* worry about looking in /etc/ppp/*-secrets
2068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
2078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
2088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_secret_check(void)
2098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 1;
2118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
2148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_choose_ip
2158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
2168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  addrp -- where to store the IP address
2178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
2188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Nothing
2198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
2208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  If RADIUS server has specified an IP address, it is stored in *addrp.
2218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
2228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
2238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_choose_ip(u_int32_t *addrp)
2248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.choose_ip) {
2268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*addrp = rstate.ip_addr;
2278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
2298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
2318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_pap_auth
2328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
2338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  user -- user-name of peer
2348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  passwd -- password supplied by peer
2358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  msgp -- Message which will be sent in PAP response
2368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  paddrs -- set to a list of possible peer IP addresses
2378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  popts -- set to a list of additional pppd options
2388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
2398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  1 if we can authenticate, -1 if we cannot.
2408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
2418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Performs PAP authentication using RADIUS
2428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
2438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
2448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_pap_auth(char *user,
2458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		char *passwd,
2468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		char **msgp,
2478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		struct wordlist **paddrs,
2488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		struct wordlist **popts)
2498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
2508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    VALUE_PAIR *send, *received;
2518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    UINT4 av_type;
2528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int result;
2538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    static char radius_msg[BUF_LEN];
2548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    radius_msg[0] = 0;
2568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    *msgp = radius_msg;
2578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (radius_init(radius_msg) < 0) {
2598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
2608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Put user with potentially realm added in rstate.user */
2638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    make_username_realm(user);
2648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (radius_pre_auth_hook) {
2668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	radius_pre_auth_hook(rstate.user,
2678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			     &rstate.authserver,
2688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			     &rstate.acctserver);
2698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
2708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    send = NULL;
2728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    received = NULL;
2738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Hack... the "port" is the ppp interface number.  Should really be
2758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project       the tty */
2768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rstate.client_port = get_client_port(portnummap ? devnam : ifname);
2778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_FRAMED;
2798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE);
2808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_PPP;
2828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE);
2838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_USER_NAME, rstate.user , 0, VENDOR_NONE);
2858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0, VENDOR_NONE);
2868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*remote_number) {
2878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0,
2888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       VENDOR_NONE);
2898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else if (ipparam)
2908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
2918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Add user specified vp's */
2938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.avp)
2948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
2958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
2968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.authserver) {
2978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	result = rc_auth_using_server(rstate.authserver,
2988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				      rstate.client_port, send,
2998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				      &received, radius_msg, NULL);
3008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else {
3018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	result = rc_auth(rstate.client_port, send, &received, radius_msg, NULL);
3028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (result == OK_RC) {
3058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (radius_setparams(received, radius_msg, NULL, NULL, NULL, NULL, 0) < 0) {
3068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    result = ERROR_RC;
3078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
3088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* free value pairs */
3118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_free(received);
3128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_free(send);
3138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (result == OK_RC) ? 1 : 0;
3158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
3168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
3188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_chap_verify
3198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
3208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  user -- name of the peer
3218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  ourname -- name for this machine
3228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  id -- the ID byte in the challenge
3238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  digest -- points to the structure representing the digest type
3248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  challenge -- the challenge string we sent (length in first byte)
3258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  response -- the response (hash) the peer sent back (length in 1st byte)
3268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  message -- space for a message to be returned to the peer
3278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  message_space -- number of bytes available at *message.
3288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
3298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  1 if the response is good, 0 if it is bad
3308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
3318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Performs CHAP, MS-CHAP and MS-CHAPv2 authentication using RADIUS.
3328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
3338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
3348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_chap_verify(char *user, char *ourname, int id,
3358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   struct chap_digest_type *digest,
3368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   unsigned char *challenge, unsigned char *response,
3378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   char *message, int message_space)
3388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
3398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    VALUE_PAIR *send, *received;
3408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    UINT4 av_type;
3418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    static char radius_msg[BUF_LEN];
3428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int result;
3438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int challenge_len, response_len;
3448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char cpassword[MAX_RESPONSE_LEN + 1];
3458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
3468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Need the RADIUS secret and Request Authenticator to decode MPPE */
3478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REQUEST_INFO request_info, *req_info = &request_info;
3488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#else
3498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    REQUEST_INFO *req_info = NULL;
3508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
3518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    challenge_len = *challenge++;
3538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    response_len = *response++;
3548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    radius_msg[0] = 0;
3568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (radius_init(radius_msg) < 0) {
3588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("%s", radius_msg);
3598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* return error for types we can't handle */
3638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((digest->code != CHAP_MD5)
3648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef CHAPMS
3658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& (digest->code != CHAP_MICROSOFT)
3668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	&& (digest->code != CHAP_MICROSOFT_V2)
3678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
3688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	) {
3698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("RADIUS: Challenge type %u unsupported", digest->code);
3708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
3718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Put user with potentially realm added in rstate.user */
3748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!rstate.done_chap_once) {
3758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	make_username_realm(user);
3768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rstate.client_port = get_client_port (portnummap ? devnam : ifname);
3778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (radius_pre_auth_hook) {
3788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    radius_pre_auth_hook(rstate.user,
3798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 &rstate.authserver,
3808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 &rstate.acctserver);
3818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
3828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
3838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    send = received = NULL;
3858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_FRAMED;
3878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add (&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE);
3888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_PPP;
3908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add (&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE);
3918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add (&send, PW_USER_NAME, rstate.user , 0, VENDOR_NONE);
3938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
3948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
3958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * add the challenge and response fields
3968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
3978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch (digest->code) {
3988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CHAP_MD5:
3998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* CHAP-Challenge and CHAP-Password */
4008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (response_len != MD5_HASH_SIZE)
4018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
4028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	cpassword[0] = id;
4038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	memcpy(&cpassword[1], response, MD5_HASH_SIZE);
4048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CHAP_CHALLENGE,
4068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		      challenge, challenge_len, VENDOR_NONE);
4078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CHAP_PASSWORD,
4088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		      cpassword, MD5_HASH_SIZE + 1, VENDOR_NONE);
4098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
4108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef CHAPMS
4128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CHAP_MICROSOFT:
4138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    {
4148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* MS-CHAP-Challenge and MS-CHAP-Response */
4158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *p = cpassword;
4168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (response_len != MS_CHAP_RESPONSE_LEN)
4188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
4198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*p++ = id;
4208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* The idiots use a different field order in RADIUS than PPP */
4211286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	*p++ = response[MS_CHAP_USENT];
4221286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	memcpy(p, response, MS_CHAP_LANMANRESP_LEN + MS_CHAP_NTRESP_LEN);
4238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE,
4258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		      challenge, challenge_len, VENDOR_MICROSOFT);
4268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_MS_CHAP_RESPONSE,
4278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		      cpassword, MS_CHAP_RESPONSE_LEN + 1, VENDOR_MICROSOFT);
4288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
4298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    case CHAP_MICROSOFT_V2:
4328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    {
4338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* MS-CHAP-Challenge and MS-CHAP2-Response */
4348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	u_char *p = cpassword;
4358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (response_len != MS_CHAP2_RESPONSE_LEN)
4378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 0;
4388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	*p++ = id;
4398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* The idiots use a different field order in RADIUS than PPP */
4401286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	*p++ = response[MS_CHAP2_FLAGS];
4411286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	memcpy(p, response, (MS_CHAP2_PEER_CHAL_LEN + MS_CHAP2_RESERVED_LEN
4421286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley			     + MS_CHAP2_NTRESP_LEN));
4438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE,
4458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		      challenge, challenge_len, VENDOR_MICROSOFT);
4468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_MS_CHAP2_RESPONSE,
4478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		      cpassword, MS_CHAP2_RESPONSE_LEN + 1, VENDOR_MICROSOFT);
4488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	break;
4498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
4518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*remote_number) {
4548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0,
4558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       VENDOR_NONE);
4568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else if (ipparam)
4578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
4588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Add user specified vp's */
4608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.avp)
4618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
4628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
4648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * make authentication with RADIUS server
4658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
4668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.authserver) {
4688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	result = rc_auth_using_server(rstate.authserver,
4698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				      rstate.client_port, send,
4708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				      &received, radius_msg, req_info);
4718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else {
4728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	result = rc_auth(rstate.client_port, send, &received, radius_msg,
4738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			 req_info);
4748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4761286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    strlcpy(message, radius_msg, message_space);
4771286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley
4788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (result == OK_RC) {
4798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (!rstate.done_chap_once) {
4808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    if (radius_setparams(received, radius_msg, req_info, digest,
4818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 challenge, message, message_space) < 0) {
4828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		error("%s", radius_msg);
4838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		result = ERROR_RC;
4848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    } else {
4858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		rstate.done_chap_once = 1;
4868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
4878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
4888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
4898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_free(received);
4918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_free (send);
4928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return (result == OK_RC);
4938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
4948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
4958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
4968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: make_username_realm
4978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
4988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  user -- the user given to pppd
4998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
5008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Nothing
5018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
5028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Copies user into rstate.user.  If it lacks a realm (no "@domain" part),
5038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* then the default realm from the radiusclient config file is added.
5048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
5058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
5068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectmake_username_realm(char *user)
5078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char *default_realm;
5098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ( user != NULL ) {
5118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strlcpy(rstate.user, user, sizeof(rstate.user));
5128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }  else {
5138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rstate.user[0] = 0;
5148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    default_realm = rc_conf_str("default_realm");
5178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!strchr(rstate.user, '@') &&
5198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default_realm &&
5208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	(*default_realm != '\0')) {
5218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strlcat(rstate.user, "@", sizeof(rstate.user));
5228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strlcat(rstate.user, default_realm, sizeof(rstate.user));
5238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
5258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
5278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_setparams
5288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
5298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  vp -- received value-pairs
5308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  msg -- buffer in which to place error message.  Holds up to BUF_LEN chars
5318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
5328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  >= 0 on success; -1 on failure
5338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
5348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Parses attributes sent by RADIUS server and sets them in pppd.
5358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
5368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
5378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info,
5388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 struct chap_digest_type *digest, unsigned char *challenge,
5398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 char *message, int message_space)
5408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
5418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t remote;
5428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int ms_chap2_success = 0;
5438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
5448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int mppe_enc_keys = 0;	/* whether or not these were received */
5458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int mppe_enc_policy = 0;
5468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int mppe_enc_types = 0;
5478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
5481286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley#ifdef MSDNS
5491286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    ipcp_options *wo = &ipcp_wantoptions[0];
5501286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    ipcp_options *ao = &ipcp_allowoptions[0];
5511286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    int got_msdns_1 = 0;
5521286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    int got_msdns_2 = 0;
5531286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    int got_wins_1 = 0;
5541286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    int got_wins_2 = 0;
5551286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley#endif
5568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Send RADIUS attributes to anyone else who might be interested */
5588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (radius_attributes_hook) {
5598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	(*radius_attributes_hook)(vp);
5608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
5618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
5638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * service type (if not framed then quit),
5648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * new IP address (RADIUS can define static IP for some users),
5658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
5668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (vp) {
5688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (vp->vendorcode == VENDOR_NONE) {
5698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    switch (vp->attribute) {
5708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_SERVICE_TYPE:
5718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* check for service type       */
5728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* if not FRAMED then exit      */
5738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (vp->lvalue != PW_FRAMED) {
5748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    slprintf(msg, BUF_LEN, "RADIUS: wrong service type %ld for %s",
5758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			     vp->lvalue, rstate.user);
5768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    return -1;
5778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
5788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
5798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_FRAMED_PROTOCOL:
5818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* check for framed protocol type       */
5828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* if not PPP then also exit            */
5838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (vp->lvalue != PW_PPP) {
5848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    slprintf(msg, BUF_LEN, "RADIUS: wrong framed protocol %ld for %s",
5858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			     vp->lvalue, rstate.user);
5868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    return -1;
5878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
5888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
5898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
5908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_SESSION_TIMEOUT:
5918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Session timeout */
5928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		maxconnect = vp->lvalue;
5938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
5941286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley           case PW_FILTER_ID:
5951286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley               /* packet filter, will be handled via ip-(up|down) script */
5961286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley               script_setenv("RADIUS_FILTER_ID", vp->strvalue, 1);
5971286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley               break;
5981286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley           case PW_FRAMED_ROUTE:
5991286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley               /* route, will be handled via ip-(up|down) script */
6001286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley               script_setenv("RADIUS_FRAMED_ROUTE", vp->strvalue, 1);
6011286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley               break;
6021286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley           case PW_IDLE_TIMEOUT:
6031286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley               /* idle parameter */
6041286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley               idle_time_limit = vp->lvalue;
6051286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley               break;
6068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MAXOCTETS
6078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_SESSION_OCTETS_LIMIT:
6088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Session traffic limit */
6098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		maxoctets = vp->lvalue;
6108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_OCTETS_DIRECTION:
6128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Session traffic limit direction check */
6138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		maxoctets_dir = ( vp->lvalue > 4 ) ? 0 : vp->lvalue ;
6148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
6168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_ACCT_INTERIM_INTERVAL:
6178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Send accounting updates every few seconds */
6188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		rstate.acct_interim_interval = vp->lvalue;
6198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* RFC says it MUST NOT be less than 60 seconds */
6208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* We use "0" to signify not sending updates */
6218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (rstate.acct_interim_interval &&
6228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    rstate.acct_interim_interval < 60) {
6238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    rstate.acct_interim_interval = 60;
6248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
6258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_FRAMED_IP_ADDRESS:
6278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* seting up remote IP addresses */
6288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		remote = vp->lvalue;
6298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (remote == 0xffffffff) {
6308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /* 0xffffffff means user should be allowed to select one */
6318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    rstate.any_ip_addr_ok = 1;
6328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} else if (remote != 0xfffffffe) {
6338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    /* 0xfffffffe means NAS should select an ip address */
6348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    remote = htonl(vp->lvalue);
6358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    if (bad_ip_adrs (remote)) {
6368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			slprintf(msg, BUF_LEN, "RADIUS: bad remote IP address %I for %s",
6378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				 remote, rstate.user);
6388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			return -1;
6398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    }
6408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    rstate.choose_ip = 1;
6418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    rstate.ip_addr = remote;
6428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
6438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6441286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley            case PW_NAS_IP_ADDRESS:
6451286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley                wo->ouraddr = htonl(vp->lvalue);
6461286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley                break;
6478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_CLASS:
6488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		/* Save Class attribute to pass it in accounting request */
6498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (vp->lvalue <= MAXCLASSLEN) {
6508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    rstate.class_len=vp->lvalue;
6518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    memcpy(rstate.class, vp->strvalue, rstate.class_len);
6528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		} /* else too big for our buffer - ignore it */
6538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
6558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	} else if (vp->vendorcode == VENDOR_MICROSOFT) {
6581286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley#ifdef CHAPMS
6598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    switch (vp->attribute) {
6608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_MS_CHAP2_SUCCESS:
6618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if ((vp->lvalue != 43) || strncmp(vp->strvalue + 1, "S=", 2)) {
6628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    slprintf(msg,BUF_LEN,"RADIUS: bad MS-CHAP2-Success packet");
6638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    return -1;
6648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
6658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (message != NULL)
6668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    strlcpy(message, vp->strvalue + 1, message_space);
6678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		ms_chap2_success = 1;
6688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
6718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_MS_CHAP_MPPE_KEYS:
6728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (radius_setmppekeys(vp, req_info, challenge) < 0) {
6738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    slprintf(msg, BUF_LEN,
6748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			     "RADIUS: bad MS-CHAP-MPPE-Keys attribute");
6758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    return -1;
6768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
6778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		mppe_enc_keys = 1;
6788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_MS_MPPE_SEND_KEY:
6818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_MS_MPPE_RECV_KEY:
6828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		if (radius_setmppekeys2(vp, req_info) < 0) {
6838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    slprintf(msg, BUF_LEN,
6848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			     "RADIUS: bad MS-MPPE-%s-Key attribute",
6858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			     (vp->attribute == PW_MS_MPPE_SEND_KEY)?
6868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project			     "Send": "Recv");
6878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		    return -1;
6888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		}
6898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		mppe_enc_keys = 1;
6908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_MS_MPPE_ENCRYPTION_POLICY:
6938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		mppe_enc_policy = vp->lvalue;	/* save for later */
6948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
6968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_MS_MPPE_ENCRYPTION_TYPES:
6978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		mppe_enc_types = vp->lvalue;	/* save for later */
6988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
6998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* MPPE */
7011286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley#ifdef MSDNS
7028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_MS_PRIMARY_DNS_SERVER:
7031286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		ao->dnsaddr[0] = htonl(vp->lvalue);
7041286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		got_msdns_1 = 1;
7051286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		if (!got_msdns_2)
7061286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		    ao->dnsaddr[1] = ao->dnsaddr[0];
7071286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		break;
7088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_MS_SECONDARY_DNS_SERVER:
7091286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		ao->dnsaddr[1] = htonl(vp->lvalue);
7101286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		got_msdns_2 = 1;
7111286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		if (!got_msdns_1)
7121286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		    ao->dnsaddr[0] = ao->dnsaddr[1];
7131286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		break;
7148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_MS_PRIMARY_NBNS_SERVER:
7151286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		ao->winsaddr[0] = htonl(vp->lvalue);
7161286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		got_wins_1 = 1;
7171286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		if (!got_wins_2)
7181286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		    ao->winsaddr[1] = ao->winsaddr[0];
7191286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		break;
7208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    case PW_MS_SECONDARY_NBNS_SERVER:
7211286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		ao->winsaddr[1] = htonl(vp->lvalue);
7221286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		got_wins_2 = 1;
7231286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		if (!got_wins_1)
7241286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley		    ao->winsaddr[0] = ao->winsaddr[1];
7258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		break;
7261286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley#endif /* MSDNS */
7278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    }
7288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* CHAPMS */
7298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
7308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	vp = vp->next;
7318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Require a valid MS-CHAP2-SUCCESS for MS-CHAPv2 auth */
7348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (digest && (digest->code == CHAP_MICROSOFT_V2) && !ms_chap2_success)
7358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
7368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
7388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
7398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Require both policy and key attributes to indicate a valid key.
7408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Note that if the policy value was '0' we don't set the key!
7418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
7428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (mppe_enc_policy && mppe_enc_keys) {
7438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	mppe_keys_set = 1;
7448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Set/modify allowed encryption types. */
7458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (mppe_enc_types)
7468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    set_mppe_enc_types(mppe_enc_policy, mppe_enc_types);
7478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
7498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
7518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
7528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MPPE
7548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
7558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_setmppekeys
7568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
7578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  vp -- value pair holding MS-CHAP-MPPE-KEYS attribute
7588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  req_info -- radius request information used for encryption
7598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
7608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  >= 0 on success; -1 on failure
7618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
7628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Decrypt the "key" provided by the RADIUS server for MPPE encryption.
7638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  See RFC 2548.
7648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
7658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
7668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info,
7678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   unsigned char *challenge)
7688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
7698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i;
7708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_CTX Context;
7718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char  plain[32];
7728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char  buf[16];
7738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (vp->lvalue != 32) {
7758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("RADIUS: Incorrect attribute length (%d) for MS-CHAP-MPPE-Keys",
7768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      vp->lvalue);
7778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
7788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
7798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memcpy(plain, vp->strvalue, sizeof(plain));
7818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Init(&Context);
7838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
7848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN);
7858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Final(buf, &Context);
7868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; i < 16; i++)
7888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	plain[i] ^= buf[i];
7898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Init(&Context);
7918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
7928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Update(&Context, vp->strvalue, 16);
7938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Final(buf, &Context);
7948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for(i = 0; i < 16; i++)
7968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	plain[i + 16] ^= buf[i];
7978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
7988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /*
7998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * Annoying.  The "key" returned is just the NTPasswordHashHash, which
8008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * the NAS (us) doesn't need; we only need the start key.  So we have
8018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     * to generate the start key, sigh.  NB: We do not support the LM-Key.
8028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project     */
8038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    mppe_set_keys(challenge, &plain[8]);
8048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
8068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
8078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
8098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_setmppekeys2
8108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
8118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  vp -- value pair holding MS-MPPE-SEND-KEY or MS-MPPE-RECV-KEY attribute
8128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  req_info -- radius request information used for encryption
8138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
8148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  >= 0 on success; -1 on failure
8158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
8168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Decrypt the key provided by the RADIUS server for MPPE encryption.
8178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  See RFC 2548.
8188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
8198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
8208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info)
8218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
8228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int i;
8238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_CTX Context;
8248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char  *salt = vp->strvalue;
8258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char  *crypt = vp->strvalue + 2;
8268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char  plain[32];
8278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_char  buf[MD5_HASH_SIZE];
8288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    char    *type = "Send";
8298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (vp->attribute == PW_MS_MPPE_RECV_KEY)
8318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	type = "Recv";
8328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (vp->lvalue != 34) {
8348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("RADIUS: Incorrect attribute length (%d) for MS-MPPE-%s-Key",
8358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      vp->lvalue, type);
8368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
8378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if ((salt[0] & 0x80) == 0) {
8408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("RADIUS: Illegal salt value for MS-MPPE-%s-Key attribute", type);
8418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
8428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    memcpy(plain, crypt, 32);
8458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Init(&Context);
8478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
8488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN);
8498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Update(&Context, salt, 2);
8508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Final(buf, &Context);
8518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    for (i = 0; i < 16; i++)
8538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	plain[i] ^= buf[i];
8548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (plain[0] != sizeof(mppe_send_key) /* 16 */) {
8568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	error("RADIUS: Incorrect key length (%d) for MS-MPPE-%s-Key attribute",
8578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	      (int) plain[0], type);
8588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
8598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Init(&Context);
8628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
8638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Update(&Context, crypt, 16);
8648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    MD5_Final(buf, &Context);
8658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    plain[16] ^= buf[0]; /* only need the first byte */
8678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (vp->attribute == PW_MS_MPPE_SEND_KEY)
8698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	memcpy(mppe_send_key, plain + 1, 16);
8708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    else
8718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	memcpy(mppe_recv_key, plain + 1, 16);
8728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
8748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
8758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif /* MPPE */
8768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
8788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_acct_start
8798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
8808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  None
8818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
8828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Nothing
8838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
8848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Sends a "start" accounting message to the RADIUS server.
8858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
8868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
8878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_acct_start(void)
8888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
8898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    UINT4 av_type;
8908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int result;
8918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    VALUE_PAIR *send = NULL;
8928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipcp_options *ho = &ipcp_hisoptions[0];
8938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t hisaddr;
8948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!rstate.initialized) {
8968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
8978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
8988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
8998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rstate.start_time = time(NULL);
9008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    strncpy(rstate.session_id, rc_mksid(), sizeof(rstate.session_id));
9028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_ACCT_SESSION_ID,
9048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   rstate.session_id, 0, VENDOR_NONE);
9058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_USER_NAME,
9068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   rstate.user, 0, VENDOR_NONE);
9078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.class_len > 0)
9098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CLASS,
9108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		      rstate.class, rstate.class_len, VENDOR_NONE);
9118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_STATUS_START;
9138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE);
9148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_FRAMED;
9168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE);
9178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_PPP;
9198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE);
9208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*remote_number) {
9228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CALLING_STATION_ID,
9238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       remote_number, 0, VENDOR_NONE);
9248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else if (ipparam)
9258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
9268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_RADIUS;
9288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE);
9298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) );
9328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE);
9338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    hisaddr = ho->hisaddr;
9358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = htonl(hisaddr);
9368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
9378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Add user specified vp's */
9398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.avp)
9408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
9418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.acctserver) {
9438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	result = rc_acct_using_server(rstate.acctserver,
9448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				      rstate.client_port, send);
9458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else {
9468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	result = rc_acct(rstate.client_port, send);
9478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_free(send);
9508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (result != OK_RC) {
9528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* RADIUS server could be down so make this a warning */
9538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	syslog(LOG_WARNING,
9548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		"Accounting START failed for %s", rstate.user);
9558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else {
9568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rstate.accounting_started = 1;
9578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Kick off periodic accounting reports */
9588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (rstate.acct_interim_interval) {
9598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    TIMEOUT(radius_acct_interim, NULL, rstate.acct_interim_interval);
9608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
9618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
9638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
9658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_acct_stop
9668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
9678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  None
9688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
9698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Nothing
9708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
9718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Sends a "stop" accounting message to the RADIUS server.
9728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
9738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
9748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_acct_stop(void)
9758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
9768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    UINT4 av_type;
9778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    VALUE_PAIR *send = NULL;
9788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipcp_options *ho = &ipcp_hisoptions[0];
9798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t hisaddr;
9808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int result;
9818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!rstate.initialized) {
9838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
9848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!rstate.accounting_started) {
9878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
9888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
9898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9901286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley    if (rstate.acct_interim_interval)
9911286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	UNTIMEOUT(radius_acct_interim, NULL);
9921286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley
9938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rstate.accounting_started = 0;
9948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id,
9958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   0, VENDOR_NONE);
9968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE);
9988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
9998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_STATUS_STOP;
10008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE);
10018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_FRAMED;
10038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE);
10048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_PPP;
10068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE);
10078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_RADIUS;
10098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE);
10108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (link_stats_valid) {
10138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	av_type = link_connect_time;
10148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE);
10158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	av_type = link_stats.bytes_out;
10178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE);
10188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	av_type = link_stats.bytes_in;
10208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE);
10218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	av_type = link_stats.pkts_out;
10238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE);
10248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	av_type = link_stats.pkts_in;
10268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_ACCT_INPUT_PACKETS, &av_type, 0, VENDOR_NONE);
10278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*remote_number) {
10308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CALLING_STATION_ID,
10318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       remote_number, 0, VENDOR_NONE);
10328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else if (ipparam)
10338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
10348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) );
10368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE);
10378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_NAS_ERROR;
10398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    switch( status ) {
10408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_OK:
10418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_USER_REQUEST:
10428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    av_type = PW_USER_REQUEST;
10438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
10448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_HANGUP:
10468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_PEER_DEAD:
10478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_CONNECT_FAILED:
10488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    av_type = PW_LOST_CARRIER;
10498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
10508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_INIT_FAILED:
10528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_OPEN_FAILED:
10538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_LOCK_FAILED:
10548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_PTYCMD_FAILED:
10558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    av_type = PW_PORT_ERROR;
10568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
10578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_PEER_AUTH_FAILED:
10598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_AUTH_TOPEER_FAILED:
10608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_NEGOTIATION_FAILED:
10618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_CNID_AUTH_FAILED:
10628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    av_type = PW_SERVICE_UNAVAILABLE;
10638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
10648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_IDLE_TIMEOUT:
10668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    av_type = PW_ACCT_IDLE_TIMEOUT;
10678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
10688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10691286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	case EXIT_CALLBACK:
10701286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    av_type = PW_CALLBACK;
10711286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley	    break;
10721286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley
10738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_CONNECT_TIME:
10748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    av_type = PW_ACCT_SESSION_TIMEOUT;
10758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
10768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#ifdef MAXOCTETS
10788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	case EXIT_TRAFFIC_LIMIT:
10798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    av_type = PW_NAS_REQUEST;
10808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
10818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#endif
10828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	default:
10848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    av_type = PW_NAS_ERROR;
10858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    break;
10868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
10878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_ACCT_TERMINATE_CAUSE, &av_type, 0, VENDOR_NONE);
10888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    hisaddr = ho->hisaddr;
10908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = htonl(hisaddr);
10918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
10928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Add user specified vp's */
10948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.avp)
10958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
10968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
10978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.acctserver) {
10988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	result = rc_acct_using_server(rstate.acctserver,
10998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				      rstate.client_port, send);
11008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else {
11018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	result = rc_acct(rstate.client_port, send);
11028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
11038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (result != OK_RC) {
11058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* RADIUS server could be down so make this a warning */
11068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	syslog(LOG_WARNING,
11078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		"Accounting STOP failed for %s", rstate.user);
11088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
11098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_free(send);
11108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
11118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
11138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_acct_interim
11148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
11158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  None
11168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
11178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Nothing
11188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
11198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Sends an interim accounting message to the RADIUS server
11208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
11218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
11228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_acct_interim(void *ignored)
11238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
11248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    UINT4 av_type;
11258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    VALUE_PAIR *send = NULL;
11268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipcp_options *ho = &ipcp_hisoptions[0];
11278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    u_int32_t hisaddr;
11288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int result;
11298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!rstate.initialized) {
11318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
11328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
11338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!rstate.accounting_started) {
11358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return;
11368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
11378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id,
11398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		   0, VENDOR_NONE);
11408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE);
11428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_STATUS_ALIVE;
11448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE);
11458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_FRAMED;
11478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE);
11488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_PPP;
11508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE);
11518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = PW_RADIUS;
11538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE);
11548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Update link stats */
11568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    update_link_stats(0);
11578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (link_stats_valid) {
11598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	link_stats_valid = 0; /* Force later code to update */
11608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	av_type = link_connect_time;
11628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE);
11638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	av_type = link_stats.bytes_out;
11658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE);
11668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	av_type = link_stats.bytes_in;
11688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE);
11698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	av_type = link_stats.pkts_out;
11718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE);
11728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	av_type = link_stats.pkts_in;
11748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_ACCT_INPUT_PACKETS, &av_type, 0, VENDOR_NONE);
11758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
11768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (*remote_number) {
11788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CALLING_STATION_ID,
11798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		       remote_number, 0, VENDOR_NONE);
11808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else if (ipparam)
11818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
11828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) );
11848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE);
11858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    hisaddr = ho->hisaddr;
11878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    av_type = htonl(hisaddr);
11888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
11898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Add user specified vp's */
11918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.avp)
11928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
11938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
11948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.acctserver) {
11958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	result = rc_acct_using_server(rstate.acctserver,
11968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project				      rstate.client_port, send);
11978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    } else {
11988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	result = rc_acct(rstate.client_port, send);
11998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (result != OK_RC) {
12028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* RADIUS server could be down so make this a warning */
12038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	syslog(LOG_WARNING,
12048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		"Interim accounting failed for %s", rstate.user);
12058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rc_avpair_free(send);
12078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Schedule another one */
12098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    TIMEOUT(radius_acct_interim, NULL, rstate.acct_interim_interval);
12108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
12118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
12138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_ip_up
12148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
12158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  opaque -- ignored
12168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  arg -- ignored
12178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
12188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Nothing
12198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
12208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Called when IPCP is up.  We'll do a start-accounting record.
12218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
12228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
12238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_ip_up(void *opaque, int arg)
12248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
12258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    radius_acct_start();
12268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
12278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
12298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_ip_down
12308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
12318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  opaque -- ignored
12328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  arg -- ignored
12338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
12348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Nothing
12358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
12368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Called when IPCP is down.  We'll do a stop-accounting record.
12378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
12388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void
12398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_ip_down(void *opaque, int arg)
12408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
12418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    radius_acct_stop();
12428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
12438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
12458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_init
12468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
12478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  msg -- buffer of size BUF_LEN for error message
12488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
12498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  negative on failure; non-negative on success
12508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
12518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Initializes radiusclient library
12528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
12538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
12548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_init(char *msg)
12558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
12568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rstate.initialized) {
12578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
12588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (config_file && *config_file) {
12618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	strlcpy(rstate.config_file, config_file, MAXPATHLEN-1);
12628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    rstate.initialized = 1;
12658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rc_read_config(rstate.config_file) != 0) {
12678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	slprintf(msg, BUF_LEN, "RADIUS: Can't read config file %s",
12688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 rstate.config_file);
12698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
12708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rc_read_dictionary(rc_conf_str("dictionary")) != 0) {
12738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	slprintf(msg, BUF_LEN, "RADIUS: Can't read dictionary file %s",
12748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 rc_conf_str("dictionary"));
12758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
12768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (rc_read_mapfile(rc_conf_str("mapfile")) != 0)	{
12798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	slprintf(msg, BUF_LEN, "RADIUS: Can't read map file %s",
12808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project		 rc_conf_str("mapfile"));
12818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return -1;
12828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    /* Add av pairs saved during option parsing */
12858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    while (avpopt) {
12868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	struct avpopt *n = avpopt->next;
12878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	rc_avpair_parse(avpopt->vpstr, &rstate.avp);
12898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(avpopt->vpstr);
12908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	free(avpopt);
12918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	avpopt = n;
12928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
12938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
12948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
12958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
12968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
12978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: get_client_port
12988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
12998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  ifname -- PPP interface name (e.g. "ppp7")
13008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
13018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  The NAS port number (e.g. 7)
13028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %DESCRIPTION:
13038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  Extracts the port number from the interface name
13048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
13058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
13068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectget_client_port(char *ifname)
13078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    int port;
13098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (sscanf(ifname, "ppp%d", &port) == 1) {
13108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return port;
13118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return rc_map2id(ifname);
13138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/**********************************************************************
13168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %FUNCTION: radius_allowed_address
13178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %ARGUMENTS:
13188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  addr -- IP address
13198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* %RETURNS:
13208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  1 if we're allowed to use that IP address; 0 if not; -1 if we do
13218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*  not know.
13228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project***********************************************************************/
13238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic int
13248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectradius_allowed_address(u_int32_t addr)
13258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    ipcp_options *wo = &ipcp_wantoptions[0];
13278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (!rstate.choose_ip) {
13298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* If RADIUS server said any address is OK, then fine... */
13308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (rstate.any_ip_addr_ok) {
13318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 1;
13328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	/* Sigh... if an address was supplied for remote host in pppd
13358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	   options, it has to match that.  */
13368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	if (wo->hisaddr != 0 && wo->hisaddr == addr) {
13378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	    return 1;
13388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	}
13398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project	return 0;
13418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    }
13428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    if (addr == rstate.ip_addr) return 1;
13438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return 0;
13448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
13458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project
13468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* Useful for other plugins */
13478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar *radius_logged_in_user(void)
13488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{
13498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project    return rstate.user;
13508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}
1351