radius.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350
  1. /***********************************************************************
  2. *
  3. * radius.c
  4. *
  5. * RADIUS plugin for pppd. Performs PAP, CHAP, MS-CHAP, MS-CHAPv2
  6. * authentication using RADIUS.
  7. *
  8. * Copyright (C) 2002 Roaring Penguin Software Inc.
  9. *
  10. * Based on a patch for ipppd, which is:
  11. * Copyright (C) 1996, Matjaz Godec <gody@elgo.si>
  12. * Copyright (C) 1996, Lars Fenneberg <in5y050@public.uni-hamburg.de>
  13. * Copyright (C) 1997, Miguel A.L. Paraz <map@iphil.net>
  14. *
  15. * Uses radiusclient library, which is:
  16. * Copyright (C) 1995,1996,1997,1998 Lars Fenneberg <lf@elemental.net>
  17. * Copyright (C) 2002 Roaring Penguin Software Inc.
  18. *
  19. * MPPE support is by Ralf Hofmann, <ralf.hofmann@elvido.net>, with
  20. * modification from Frank Cusack, <frank@google.com>.
  21. *
  22. * This plugin may be distributed according to the terms of the GNU
  23. * General Public License, version 2 or (at your option) any later version.
  24. *
  25. ***********************************************************************/
  26. static char const RCSID[] =
  27. "$Id: radius.c,v 1.32 2008/05/26 09:18:08 paulus Exp $";
  28. #include "pppd.h"
  29. #include "chap-new.h"
  30. #ifdef CHAPMS
  31. #include "chap_ms.h"
  32. #ifdef MPPE
  33. #include "md5.h"
  34. #endif
  35. #endif
  36. #include "radiusclient.h"
  37. #include "fsm.h"
  38. #include "ipcp.h"
  39. #include <syslog.h>
  40. #include <sys/types.h>
  41. #include <sys/time.h>
  42. #include <string.h>
  43. #include <netinet/in.h>
  44. #include <stdlib.h>
  45. #define BUF_LEN 1024
  46. #define MD5_HASH_SIZE 16
  47. #define MSDNS 1
  48. static char *config_file = NULL;
  49. static int add_avp(char **);
  50. static struct avpopt {
  51. char *vpstr;
  52. struct avpopt *next;
  53. } *avpopt = NULL;
  54. static bool portnummap = 0;
  55. static option_t Options[] = {
  56. { "radius-config-file", o_string, &config_file },
  57. { "avpair", o_special, add_avp },
  58. { "map-to-ttyname", o_bool, &portnummap,
  59. "Set Radius NAS-Port attribute value via libradiusclient library", OPT_PRIO | 1 },
  60. { "map-to-ifname", o_bool, &portnummap,
  61. "Set Radius NAS-Port attribute to number as in interface name (Default)", OPT_PRIOSUB | 0 },
  62. { NULL }
  63. };
  64. static int radius_secret_check(void);
  65. static int radius_pap_auth(char *user,
  66. char *passwd,
  67. char **msgp,
  68. struct wordlist **paddrs,
  69. struct wordlist **popts);
  70. static int radius_chap_verify(char *user, char *ourname, int id,
  71. struct chap_digest_type *digest,
  72. unsigned char *challenge,
  73. unsigned char *response,
  74. char *message, int message_space);
  75. static void radius_ip_up(void *opaque, int arg);
  76. static void radius_ip_down(void *opaque, int arg);
  77. static void make_username_realm(char *user);
  78. static int radius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info,
  79. struct chap_digest_type *digest,
  80. unsigned char *challenge,
  81. char *message, int message_space);
  82. static void radius_choose_ip(u_int32_t *addrp);
  83. static int radius_init(char *msg);
  84. static int get_client_port(char *ifname);
  85. static int radius_allowed_address(u_int32_t addr);
  86. static void radius_acct_interim(void *);
  87. #ifdef MPPE
  88. static int radius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info,
  89. unsigned char *);
  90. static int radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info);
  91. #endif
  92. #ifndef MAXSESSIONID
  93. #define MAXSESSIONID 32
  94. #endif
  95. #ifndef MAXCLASSLEN
  96. #define MAXCLASSLEN 500
  97. #endif
  98. struct radius_state {
  99. int accounting_started;
  100. int initialized;
  101. int client_port;
  102. int choose_ip;
  103. int any_ip_addr_ok;
  104. int done_chap_once;
  105. u_int32_t ip_addr;
  106. char user[MAXNAMELEN];
  107. char config_file[MAXPATHLEN];
  108. char session_id[MAXSESSIONID + 1];
  109. time_t start_time;
  110. int acct_interim_interval;
  111. SERVER *authserver; /* Authentication server to use */
  112. SERVER *acctserver; /* Accounting server to use */
  113. int class_len;
  114. char class[MAXCLASSLEN];
  115. VALUE_PAIR *avp; /* Additional (user supplied) vp's to send to server */
  116. };
  117. void (*radius_attributes_hook)(VALUE_PAIR *) = NULL;
  118. /* The pre_auth_hook MAY set authserver and acctserver if it wants.
  119. In that case, they override the values in the radiusclient.conf file */
  120. void (*radius_pre_auth_hook)(char const *user,
  121. SERVER **authserver,
  122. SERVER **acctserver) = NULL;
  123. static struct radius_state rstate;
  124. char pppd_version[] = VERSION;
  125. /**********************************************************************
  126. * %FUNCTION: plugin_init
  127. * %ARGUMENTS:
  128. * None
  129. * %RETURNS:
  130. * Nothing
  131. * %DESCRIPTION:
  132. * Initializes RADIUS plugin.
  133. ***********************************************************************/
  134. void
  135. plugin_init(void)
  136. {
  137. pap_check_hook = radius_secret_check;
  138. pap_auth_hook = radius_pap_auth;
  139. chap_check_hook = radius_secret_check;
  140. chap_verify_hook = radius_chap_verify;
  141. ip_choose_hook = radius_choose_ip;
  142. allowed_address_hook = radius_allowed_address;
  143. add_notifier(&ip_up_notifier, radius_ip_up, NULL);
  144. add_notifier(&ip_down_notifier, radius_ip_down, NULL);
  145. memset(&rstate, 0, sizeof(rstate));
  146. strlcpy(rstate.config_file, "/etc/radiusclient/radiusclient.conf",
  147. sizeof(rstate.config_file));
  148. add_options(Options);
  149. info("RADIUS plugin initialized.");
  150. }
  151. /**********************************************************************
  152. * %FUNCTION: add_avp
  153. * %ARGUMENTS:
  154. * argv -- the <attribute=value> pair to add
  155. * %RETURNS:
  156. * 1
  157. * %DESCRIPTION:
  158. * Adds an av pair to be passed on to the RADIUS server on each request.
  159. ***********************************************************************/
  160. static int
  161. add_avp(char **argv)
  162. {
  163. struct avpopt *p = malloc(sizeof(struct avpopt));
  164. /* Append to a list of vp's for later parsing */
  165. p->vpstr = strdup(*argv);
  166. p->next = avpopt;
  167. avpopt = p;
  168. return 1;
  169. }
  170. /**********************************************************************
  171. * %FUNCTION: radius_secret_check
  172. * %ARGUMENTS:
  173. * None
  174. * %RETURNS:
  175. * 1 -- we are ALWAYS willing to supply a secret. :-)
  176. * %DESCRIPTION:
  177. * Tells pppd that we will try to authenticate the peer, and not to
  178. * worry about looking in /etc/ppp/*-secrets
  179. ***********************************************************************/
  180. static int
  181. radius_secret_check(void)
  182. {
  183. return 1;
  184. }
  185. /**********************************************************************
  186. * %FUNCTION: radius_choose_ip
  187. * %ARGUMENTS:
  188. * addrp -- where to store the IP address
  189. * %RETURNS:
  190. * Nothing
  191. * %DESCRIPTION:
  192. * If RADIUS server has specified an IP address, it is stored in *addrp.
  193. ***********************************************************************/
  194. static void
  195. radius_choose_ip(u_int32_t *addrp)
  196. {
  197. if (rstate.choose_ip) {
  198. *addrp = rstate.ip_addr;
  199. }
  200. }
  201. /**********************************************************************
  202. * %FUNCTION: radius_pap_auth
  203. * %ARGUMENTS:
  204. * user -- user-name of peer
  205. * passwd -- password supplied by peer
  206. * msgp -- Message which will be sent in PAP response
  207. * paddrs -- set to a list of possible peer IP addresses
  208. * popts -- set to a list of additional pppd options
  209. * %RETURNS:
  210. * 1 if we can authenticate, -1 if we cannot.
  211. * %DESCRIPTION:
  212. * Performs PAP authentication using RADIUS
  213. ***********************************************************************/
  214. static int
  215. radius_pap_auth(char *user,
  216. char *passwd,
  217. char **msgp,
  218. struct wordlist **paddrs,
  219. struct wordlist **popts)
  220. {
  221. VALUE_PAIR *send, *received;
  222. UINT4 av_type;
  223. int result;
  224. static char radius_msg[BUF_LEN];
  225. radius_msg[0] = 0;
  226. *msgp = radius_msg;
  227. if (radius_init(radius_msg) < 0) {
  228. return 0;
  229. }
  230. /* Put user with potentially realm added in rstate.user */
  231. make_username_realm(user);
  232. if (radius_pre_auth_hook) {
  233. radius_pre_auth_hook(rstate.user,
  234. &rstate.authserver,
  235. &rstate.acctserver);
  236. }
  237. send = NULL;
  238. received = NULL;
  239. /* Hack... the "port" is the ppp interface number. Should really be
  240. the tty */
  241. rstate.client_port = get_client_port(portnummap ? devnam : ifname);
  242. av_type = PW_FRAMED;
  243. rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE);
  244. av_type = PW_PPP;
  245. rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE);
  246. rc_avpair_add(&send, PW_USER_NAME, rstate.user , 0, VENDOR_NONE);
  247. rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0, VENDOR_NONE);
  248. if (*remote_number) {
  249. rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0,
  250. VENDOR_NONE);
  251. } else if (ipparam)
  252. rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
  253. /* Add user specified vp's */
  254. if (rstate.avp)
  255. rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
  256. if (rstate.authserver) {
  257. result = rc_auth_using_server(rstate.authserver,
  258. rstate.client_port, send,
  259. &received, radius_msg, NULL);
  260. } else {
  261. result = rc_auth(rstate.client_port, send, &received, radius_msg, NULL);
  262. }
  263. if (result == OK_RC) {
  264. if (radius_setparams(received, radius_msg, NULL, NULL, NULL, NULL, 0) < 0) {
  265. result = ERROR_RC;
  266. }
  267. }
  268. /* free value pairs */
  269. rc_avpair_free(received);
  270. rc_avpair_free(send);
  271. return (result == OK_RC) ? 1 : 0;
  272. }
  273. /**********************************************************************
  274. * %FUNCTION: radius_chap_verify
  275. * %ARGUMENTS:
  276. * user -- name of the peer
  277. * ourname -- name for this machine
  278. * id -- the ID byte in the challenge
  279. * digest -- points to the structure representing the digest type
  280. * challenge -- the challenge string we sent (length in first byte)
  281. * response -- the response (hash) the peer sent back (length in 1st byte)
  282. * message -- space for a message to be returned to the peer
  283. * message_space -- number of bytes available at *message.
  284. * %RETURNS:
  285. * 1 if the response is good, 0 if it is bad
  286. * %DESCRIPTION:
  287. * Performs CHAP, MS-CHAP and MS-CHAPv2 authentication using RADIUS.
  288. ***********************************************************************/
  289. static int
  290. radius_chap_verify(char *user, char *ourname, int id,
  291. struct chap_digest_type *digest,
  292. unsigned char *challenge, unsigned char *response,
  293. char *message, int message_space)
  294. {
  295. VALUE_PAIR *send, *received;
  296. UINT4 av_type;
  297. static char radius_msg[BUF_LEN];
  298. int result;
  299. int challenge_len, response_len;
  300. u_char cpassword[MAX_RESPONSE_LEN + 1];
  301. #ifdef MPPE
  302. /* Need the RADIUS secret and Request Authenticator to decode MPPE */
  303. REQUEST_INFO request_info, *req_info = &request_info;
  304. #else
  305. REQUEST_INFO *req_info = NULL;
  306. #endif
  307. challenge_len = *challenge++;
  308. response_len = *response++;
  309. radius_msg[0] = 0;
  310. if (radius_init(radius_msg) < 0) {
  311. error("%s", radius_msg);
  312. return 0;
  313. }
  314. /* return error for types we can't handle */
  315. if ((digest->code != CHAP_MD5)
  316. #ifdef CHAPMS
  317. && (digest->code != CHAP_MICROSOFT)
  318. && (digest->code != CHAP_MICROSOFT_V2)
  319. #endif
  320. ) {
  321. error("RADIUS: Challenge type %u unsupported", digest->code);
  322. return 0;
  323. }
  324. /* Put user with potentially realm added in rstate.user */
  325. if (!rstate.done_chap_once) {
  326. make_username_realm(user);
  327. rstate.client_port = get_client_port (portnummap ? devnam : ifname);
  328. if (radius_pre_auth_hook) {
  329. radius_pre_auth_hook(rstate.user,
  330. &rstate.authserver,
  331. &rstate.acctserver);
  332. }
  333. }
  334. send = received = NULL;
  335. av_type = PW_FRAMED;
  336. rc_avpair_add (&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE);
  337. av_type = PW_PPP;
  338. rc_avpair_add (&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE);
  339. rc_avpair_add (&send, PW_USER_NAME, rstate.user , 0, VENDOR_NONE);
  340. /*
  341. * add the challenge and response fields
  342. */
  343. switch (digest->code) {
  344. case CHAP_MD5:
  345. /* CHAP-Challenge and CHAP-Password */
  346. if (response_len != MD5_HASH_SIZE)
  347. return 0;
  348. cpassword[0] = id;
  349. memcpy(&cpassword[1], response, MD5_HASH_SIZE);
  350. rc_avpair_add(&send, PW_CHAP_CHALLENGE,
  351. challenge, challenge_len, VENDOR_NONE);
  352. rc_avpair_add(&send, PW_CHAP_PASSWORD,
  353. cpassword, MD5_HASH_SIZE + 1, VENDOR_NONE);
  354. break;
  355. #ifdef CHAPMS
  356. case CHAP_MICROSOFT:
  357. {
  358. /* MS-CHAP-Challenge and MS-CHAP-Response */
  359. u_char *p = cpassword;
  360. if (response_len != MS_CHAP_RESPONSE_LEN)
  361. return 0;
  362. *p++ = id;
  363. /* The idiots use a different field order in RADIUS than PPP */
  364. *p++ = response[MS_CHAP_USENT];
  365. memcpy(p, response, MS_CHAP_LANMANRESP_LEN + MS_CHAP_NTRESP_LEN);
  366. rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE,
  367. challenge, challenge_len, VENDOR_MICROSOFT);
  368. rc_avpair_add(&send, PW_MS_CHAP_RESPONSE,
  369. cpassword, MS_CHAP_RESPONSE_LEN + 1, VENDOR_MICROSOFT);
  370. break;
  371. }
  372. case CHAP_MICROSOFT_V2:
  373. {
  374. /* MS-CHAP-Challenge and MS-CHAP2-Response */
  375. u_char *p = cpassword;
  376. if (response_len != MS_CHAP2_RESPONSE_LEN)
  377. return 0;
  378. *p++ = id;
  379. /* The idiots use a different field order in RADIUS than PPP */
  380. *p++ = response[MS_CHAP2_FLAGS];
  381. memcpy(p, response, (MS_CHAP2_PEER_CHAL_LEN + MS_CHAP2_RESERVED_LEN
  382. + MS_CHAP2_NTRESP_LEN));
  383. rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE,
  384. challenge, challenge_len, VENDOR_MICROSOFT);
  385. rc_avpair_add(&send, PW_MS_CHAP2_RESPONSE,
  386. cpassword, MS_CHAP2_RESPONSE_LEN + 1, VENDOR_MICROSOFT);
  387. break;
  388. }
  389. #endif
  390. }
  391. if (*remote_number) {
  392. rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0,
  393. VENDOR_NONE);
  394. } else if (ipparam)
  395. rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
  396. /* Add user specified vp's */
  397. if (rstate.avp)
  398. rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
  399. /*
  400. * make authentication with RADIUS server
  401. */
  402. if (rstate.authserver) {
  403. result = rc_auth_using_server(rstate.authserver,
  404. rstate.client_port, send,
  405. &received, radius_msg, req_info);
  406. } else {
  407. result = rc_auth(rstate.client_port, send, &received, radius_msg,
  408. req_info);
  409. }
  410. strlcpy(message, radius_msg, message_space);
  411. if (result == OK_RC) {
  412. if (!rstate.done_chap_once) {
  413. if (radius_setparams(received, radius_msg, req_info, digest,
  414. challenge, message, message_space) < 0) {
  415. error("%s", radius_msg);
  416. result = ERROR_RC;
  417. } else {
  418. rstate.done_chap_once = 1;
  419. }
  420. }
  421. }
  422. rc_avpair_free(received);
  423. rc_avpair_free (send);
  424. return (result == OK_RC);
  425. }
  426. /**********************************************************************
  427. * %FUNCTION: make_username_realm
  428. * %ARGUMENTS:
  429. * user -- the user given to pppd
  430. * %RETURNS:
  431. * Nothing
  432. * %DESCRIPTION:
  433. * Copies user into rstate.user. If it lacks a realm (no "@domain" part),
  434. * then the default realm from the radiusclient config file is added.
  435. ***********************************************************************/
  436. static void
  437. make_username_realm(char *user)
  438. {
  439. char *default_realm;
  440. if ( user != NULL ) {
  441. strlcpy(rstate.user, user, sizeof(rstate.user));
  442. } else {
  443. rstate.user[0] = 0;
  444. }
  445. default_realm = rc_conf_str("default_realm");
  446. if (!strchr(rstate.user, '@') &&
  447. default_realm &&
  448. (*default_realm != '\0')) {
  449. strlcat(rstate.user, "@", sizeof(rstate.user));
  450. strlcat(rstate.user, default_realm, sizeof(rstate.user));
  451. }
  452. }
  453. /**********************************************************************
  454. * %FUNCTION: radius_setparams
  455. * %ARGUMENTS:
  456. * vp -- received value-pairs
  457. * msg -- buffer in which to place error message. Holds up to BUF_LEN chars
  458. * %RETURNS:
  459. * >= 0 on success; -1 on failure
  460. * %DESCRIPTION:
  461. * Parses attributes sent by RADIUS server and sets them in pppd.
  462. ***********************************************************************/
  463. static int
  464. radius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info,
  465. struct chap_digest_type *digest, unsigned char *challenge,
  466. char *message, int message_space)
  467. {
  468. u_int32_t remote;
  469. int ms_chap2_success = 0;
  470. #ifdef MPPE
  471. int mppe_enc_keys = 0; /* whether or not these were received */
  472. int mppe_enc_policy = 0;
  473. int mppe_enc_types = 0;
  474. #endif
  475. #ifdef MSDNS
  476. ipcp_options *wo = &ipcp_wantoptions[0];
  477. ipcp_options *ao = &ipcp_allowoptions[0];
  478. int got_msdns_1 = 0;
  479. int got_msdns_2 = 0;
  480. int got_wins_1 = 0;
  481. int got_wins_2 = 0;
  482. #endif
  483. /* Send RADIUS attributes to anyone else who might be interested */
  484. if (radius_attributes_hook) {
  485. (*radius_attributes_hook)(vp);
  486. }
  487. /*
  488. * service type (if not framed then quit),
  489. * new IP address (RADIUS can define static IP for some users),
  490. */
  491. while (vp) {
  492. if (vp->vendorcode == VENDOR_NONE) {
  493. switch (vp->attribute) {
  494. case PW_SERVICE_TYPE:
  495. /* check for service type */
  496. /* if not FRAMED then exit */
  497. if (vp->lvalue != PW_FRAMED) {
  498. slprintf(msg, BUF_LEN, "RADIUS: wrong service type %ld for %s",
  499. vp->lvalue, rstate.user);
  500. return -1;
  501. }
  502. break;
  503. case PW_FRAMED_PROTOCOL:
  504. /* check for framed protocol type */
  505. /* if not PPP then also exit */
  506. if (vp->lvalue != PW_PPP) {
  507. slprintf(msg, BUF_LEN, "RADIUS: wrong framed protocol %ld for %s",
  508. vp->lvalue, rstate.user);
  509. return -1;
  510. }
  511. break;
  512. case PW_SESSION_TIMEOUT:
  513. /* Session timeout */
  514. maxconnect = vp->lvalue;
  515. break;
  516. case PW_FILTER_ID:
  517. /* packet filter, will be handled via ip-(up|down) script */
  518. script_setenv("RADIUS_FILTER_ID", vp->strvalue, 1);
  519. break;
  520. case PW_FRAMED_ROUTE:
  521. /* route, will be handled via ip-(up|down) script */
  522. script_setenv("RADIUS_FRAMED_ROUTE", vp->strvalue, 1);
  523. break;
  524. case PW_IDLE_TIMEOUT:
  525. /* idle parameter */
  526. idle_time_limit = vp->lvalue;
  527. break;
  528. #ifdef MAXOCTETS
  529. case PW_SESSION_OCTETS_LIMIT:
  530. /* Session traffic limit */
  531. maxoctets = vp->lvalue;
  532. break;
  533. case PW_OCTETS_DIRECTION:
  534. /* Session traffic limit direction check */
  535. maxoctets_dir = ( vp->lvalue > 4 ) ? 0 : vp->lvalue ;
  536. break;
  537. #endif
  538. case PW_ACCT_INTERIM_INTERVAL:
  539. /* Send accounting updates every few seconds */
  540. rstate.acct_interim_interval = vp->lvalue;
  541. /* RFC says it MUST NOT be less than 60 seconds */
  542. /* We use "0" to signify not sending updates */
  543. if (rstate.acct_interim_interval &&
  544. rstate.acct_interim_interval < 60) {
  545. rstate.acct_interim_interval = 60;
  546. }
  547. break;
  548. case PW_FRAMED_IP_ADDRESS:
  549. /* seting up remote IP addresses */
  550. remote = vp->lvalue;
  551. if (remote == 0xffffffff) {
  552. /* 0xffffffff means user should be allowed to select one */
  553. rstate.any_ip_addr_ok = 1;
  554. } else if (remote != 0xfffffffe) {
  555. /* 0xfffffffe means NAS should select an ip address */
  556. remote = htonl(vp->lvalue);
  557. if (bad_ip_adrs (remote)) {
  558. slprintf(msg, BUF_LEN, "RADIUS: bad remote IP address %I for %s",
  559. remote, rstate.user);
  560. return -1;
  561. }
  562. rstate.choose_ip = 1;
  563. rstate.ip_addr = remote;
  564. }
  565. break;
  566. case PW_NAS_IP_ADDRESS:
  567. wo->ouraddr = htonl(vp->lvalue);
  568. break;
  569. case PW_CLASS:
  570. /* Save Class attribute to pass it in accounting request */
  571. if (vp->lvalue <= MAXCLASSLEN) {
  572. rstate.class_len=vp->lvalue;
  573. memcpy(rstate.class, vp->strvalue, rstate.class_len);
  574. } /* else too big for our buffer - ignore it */
  575. break;
  576. }
  577. } else if (vp->vendorcode == VENDOR_MICROSOFT) {
  578. #ifdef CHAPMS
  579. switch (vp->attribute) {
  580. case PW_MS_CHAP2_SUCCESS:
  581. if ((vp->lvalue != 43) || strncmp(vp->strvalue + 1, "S=", 2)) {
  582. slprintf(msg,BUF_LEN,"RADIUS: bad MS-CHAP2-Success packet");
  583. return -1;
  584. }
  585. if (message != NULL)
  586. strlcpy(message, vp->strvalue + 1, message_space);
  587. ms_chap2_success = 1;
  588. break;
  589. #ifdef MPPE
  590. case PW_MS_CHAP_MPPE_KEYS:
  591. if (radius_setmppekeys(vp, req_info, challenge) < 0) {
  592. slprintf(msg, BUF_LEN,
  593. "RADIUS: bad MS-CHAP-MPPE-Keys attribute");
  594. return -1;
  595. }
  596. mppe_enc_keys = 1;
  597. break;
  598. case PW_MS_MPPE_SEND_KEY:
  599. case PW_MS_MPPE_RECV_KEY:
  600. if (radius_setmppekeys2(vp, req_info) < 0) {
  601. slprintf(msg, BUF_LEN,
  602. "RADIUS: bad MS-MPPE-%s-Key attribute",
  603. (vp->attribute == PW_MS_MPPE_SEND_KEY)?
  604. "Send": "Recv");
  605. return -1;
  606. }
  607. mppe_enc_keys = 1;
  608. break;
  609. case PW_MS_MPPE_ENCRYPTION_POLICY:
  610. mppe_enc_policy = vp->lvalue; /* save for later */
  611. break;
  612. case PW_MS_MPPE_ENCRYPTION_TYPES:
  613. mppe_enc_types = vp->lvalue; /* save for later */
  614. break;
  615. #endif /* MPPE */
  616. #ifdef MSDNS
  617. case PW_MS_PRIMARY_DNS_SERVER:
  618. ao->dnsaddr[0] = htonl(vp->lvalue);
  619. got_msdns_1 = 1;
  620. if (!got_msdns_2)
  621. ao->dnsaddr[1] = ao->dnsaddr[0];
  622. break;
  623. case PW_MS_SECONDARY_DNS_SERVER:
  624. ao->dnsaddr[1] = htonl(vp->lvalue);
  625. got_msdns_2 = 1;
  626. if (!got_msdns_1)
  627. ao->dnsaddr[0] = ao->dnsaddr[1];
  628. break;
  629. case PW_MS_PRIMARY_NBNS_SERVER:
  630. ao->winsaddr[0] = htonl(vp->lvalue);
  631. got_wins_1 = 1;
  632. if (!got_wins_2)
  633. ao->winsaddr[1] = ao->winsaddr[0];
  634. break;
  635. case PW_MS_SECONDARY_NBNS_SERVER:
  636. ao->winsaddr[1] = htonl(vp->lvalue);
  637. got_wins_2 = 1;
  638. if (!got_wins_1)
  639. ao->winsaddr[0] = ao->winsaddr[1];
  640. break;
  641. #endif /* MSDNS */
  642. }
  643. #endif /* CHAPMS */
  644. }
  645. vp = vp->next;
  646. }
  647. /* Require a valid MS-CHAP2-SUCCESS for MS-CHAPv2 auth */
  648. if (digest && (digest->code == CHAP_MICROSOFT_V2) && !ms_chap2_success)
  649. return -1;
  650. #ifdef MPPE
  651. /*
  652. * Require both policy and key attributes to indicate a valid key.
  653. * Note that if the policy value was '0' we don't set the key!
  654. */
  655. if (mppe_enc_policy && mppe_enc_keys) {
  656. mppe_keys_set = 1;
  657. /* Set/modify allowed encryption types. */
  658. if (mppe_enc_types)
  659. set_mppe_enc_types(mppe_enc_policy, mppe_enc_types);
  660. }
  661. #endif
  662. return 0;
  663. }
  664. #ifdef MPPE
  665. /**********************************************************************
  666. * %FUNCTION: radius_setmppekeys
  667. * %ARGUMENTS:
  668. * vp -- value pair holding MS-CHAP-MPPE-KEYS attribute
  669. * req_info -- radius request information used for encryption
  670. * %RETURNS:
  671. * >= 0 on success; -1 on failure
  672. * %DESCRIPTION:
  673. * Decrypt the "key" provided by the RADIUS server for MPPE encryption.
  674. * See RFC 2548.
  675. ***********************************************************************/
  676. static int
  677. radius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info,
  678. unsigned char *challenge)
  679. {
  680. int i;
  681. MD5_CTX Context;
  682. u_char plain[32];
  683. u_char buf[16];
  684. if (vp->lvalue != 32) {
  685. error("RADIUS: Incorrect attribute length (%d) for MS-CHAP-MPPE-Keys",
  686. vp->lvalue);
  687. return -1;
  688. }
  689. memcpy(plain, vp->strvalue, sizeof(plain));
  690. MD5_Init(&Context);
  691. MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
  692. MD5_Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN);
  693. MD5_Final(buf, &Context);
  694. for (i = 0; i < 16; i++)
  695. plain[i] ^= buf[i];
  696. MD5_Init(&Context);
  697. MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
  698. MD5_Update(&Context, vp->strvalue, 16);
  699. MD5_Final(buf, &Context);
  700. for(i = 0; i < 16; i++)
  701. plain[i + 16] ^= buf[i];
  702. /*
  703. * Annoying. The "key" returned is just the NTPasswordHashHash, which
  704. * the NAS (us) doesn't need; we only need the start key. So we have
  705. * to generate the start key, sigh. NB: We do not support the LM-Key.
  706. */
  707. mppe_set_keys(challenge, &plain[8]);
  708. return 0;
  709. }
  710. /**********************************************************************
  711. * %FUNCTION: radius_setmppekeys2
  712. * %ARGUMENTS:
  713. * vp -- value pair holding MS-MPPE-SEND-KEY or MS-MPPE-RECV-KEY attribute
  714. * req_info -- radius request information used for encryption
  715. * %RETURNS:
  716. * >= 0 on success; -1 on failure
  717. * %DESCRIPTION:
  718. * Decrypt the key provided by the RADIUS server for MPPE encryption.
  719. * See RFC 2548.
  720. ***********************************************************************/
  721. static int
  722. radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info)
  723. {
  724. int i;
  725. MD5_CTX Context;
  726. u_char *salt = vp->strvalue;
  727. u_char *crypt = vp->strvalue + 2;
  728. u_char plain[32];
  729. u_char buf[MD5_HASH_SIZE];
  730. char *type = "Send";
  731. if (vp->attribute == PW_MS_MPPE_RECV_KEY)
  732. type = "Recv";
  733. if (vp->lvalue != 34) {
  734. error("RADIUS: Incorrect attribute length (%d) for MS-MPPE-%s-Key",
  735. vp->lvalue, type);
  736. return -1;
  737. }
  738. if ((salt[0] & 0x80) == 0) {
  739. error("RADIUS: Illegal salt value for MS-MPPE-%s-Key attribute", type);
  740. return -1;
  741. }
  742. memcpy(plain, crypt, 32);
  743. MD5_Init(&Context);
  744. MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
  745. MD5_Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN);
  746. MD5_Update(&Context, salt, 2);
  747. MD5_Final(buf, &Context);
  748. for (i = 0; i < 16; i++)
  749. plain[i] ^= buf[i];
  750. if (plain[0] != sizeof(mppe_send_key) /* 16 */) {
  751. error("RADIUS: Incorrect key length (%d) for MS-MPPE-%s-Key attribute",
  752. (int) plain[0], type);
  753. return -1;
  754. }
  755. MD5_Init(&Context);
  756. MD5_Update(&Context, req_info->secret, strlen(req_info->secret));
  757. MD5_Update(&Context, crypt, 16);
  758. MD5_Final(buf, &Context);
  759. plain[16] ^= buf[0]; /* only need the first byte */
  760. if (vp->attribute == PW_MS_MPPE_SEND_KEY)
  761. memcpy(mppe_send_key, plain + 1, 16);
  762. else
  763. memcpy(mppe_recv_key, plain + 1, 16);
  764. return 0;
  765. }
  766. #endif /* MPPE */
  767. /**********************************************************************
  768. * %FUNCTION: radius_acct_start
  769. * %ARGUMENTS:
  770. * None
  771. * %RETURNS:
  772. * Nothing
  773. * %DESCRIPTION:
  774. * Sends a "start" accounting message to the RADIUS server.
  775. ***********************************************************************/
  776. static void
  777. radius_acct_start(void)
  778. {
  779. UINT4 av_type;
  780. int result;
  781. VALUE_PAIR *send = NULL;
  782. ipcp_options *ho = &ipcp_hisoptions[0];
  783. u_int32_t hisaddr;
  784. if (!rstate.initialized) {
  785. return;
  786. }
  787. rstate.start_time = time(NULL);
  788. strncpy(rstate.session_id, rc_mksid(), sizeof(rstate.session_id));
  789. rc_avpair_add(&send, PW_ACCT_SESSION_ID,
  790. rstate.session_id, 0, VENDOR_NONE);
  791. rc_avpair_add(&send, PW_USER_NAME,
  792. rstate.user, 0, VENDOR_NONE);
  793. if (rstate.class_len > 0)
  794. rc_avpair_add(&send, PW_CLASS,
  795. rstate.class, rstate.class_len, VENDOR_NONE);
  796. av_type = PW_STATUS_START;
  797. rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE);
  798. av_type = PW_FRAMED;
  799. rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE);
  800. av_type = PW_PPP;
  801. rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE);
  802. if (*remote_number) {
  803. rc_avpair_add(&send, PW_CALLING_STATION_ID,
  804. remote_number, 0, VENDOR_NONE);
  805. } else if (ipparam)
  806. rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
  807. av_type = PW_RADIUS;
  808. rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE);
  809. av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) );
  810. rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE);
  811. hisaddr = ho->hisaddr;
  812. av_type = htonl(hisaddr);
  813. rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
  814. /* Add user specified vp's */
  815. if (rstate.avp)
  816. rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
  817. if (rstate.acctserver) {
  818. result = rc_acct_using_server(rstate.acctserver,
  819. rstate.client_port, send);
  820. } else {
  821. result = rc_acct(rstate.client_port, send);
  822. }
  823. rc_avpair_free(send);
  824. if (result != OK_RC) {
  825. /* RADIUS server could be down so make this a warning */
  826. syslog(LOG_WARNING,
  827. "Accounting START failed for %s", rstate.user);
  828. } else {
  829. rstate.accounting_started = 1;
  830. /* Kick off periodic accounting reports */
  831. if (rstate.acct_interim_interval) {
  832. TIMEOUT(radius_acct_interim, NULL, rstate.acct_interim_interval);
  833. }
  834. }
  835. }
  836. /**********************************************************************
  837. * %FUNCTION: radius_acct_stop
  838. * %ARGUMENTS:
  839. * None
  840. * %RETURNS:
  841. * Nothing
  842. * %DESCRIPTION:
  843. * Sends a "stop" accounting message to the RADIUS server.
  844. ***********************************************************************/
  845. static void
  846. radius_acct_stop(void)
  847. {
  848. UINT4 av_type;
  849. VALUE_PAIR *send = NULL;
  850. ipcp_options *ho = &ipcp_hisoptions[0];
  851. u_int32_t hisaddr;
  852. int result;
  853. if (!rstate.initialized) {
  854. return;
  855. }
  856. if (!rstate.accounting_started) {
  857. return;
  858. }
  859. if (rstate.acct_interim_interval)
  860. UNTIMEOUT(radius_acct_interim, NULL);
  861. rstate.accounting_started = 0;
  862. rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id,
  863. 0, VENDOR_NONE);
  864. rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE);
  865. av_type = PW_STATUS_STOP;
  866. rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE);
  867. av_type = PW_FRAMED;
  868. rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE);
  869. av_type = PW_PPP;
  870. rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE);
  871. av_type = PW_RADIUS;
  872. rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE);
  873. if (link_stats_valid) {
  874. av_type = link_connect_time;
  875. rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE);
  876. av_type = link_stats.bytes_out;
  877. rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE);
  878. av_type = link_stats.bytes_in;
  879. rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE);
  880. av_type = link_stats.pkts_out;
  881. rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE);
  882. av_type = link_stats.pkts_in;
  883. rc_avpair_add(&send, PW_ACCT_INPUT_PACKETS, &av_type, 0, VENDOR_NONE);
  884. }
  885. if (*remote_number) {
  886. rc_avpair_add(&send, PW_CALLING_STATION_ID,
  887. remote_number, 0, VENDOR_NONE);
  888. } else if (ipparam)
  889. rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
  890. av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) );
  891. rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE);
  892. av_type = PW_NAS_ERROR;
  893. switch( status ) {
  894. case EXIT_OK:
  895. case EXIT_USER_REQUEST:
  896. av_type = PW_USER_REQUEST;
  897. break;
  898. case EXIT_HANGUP:
  899. case EXIT_PEER_DEAD:
  900. case EXIT_CONNECT_FAILED:
  901. av_type = PW_LOST_CARRIER;
  902. break;
  903. case EXIT_INIT_FAILED:
  904. case EXIT_OPEN_FAILED:
  905. case EXIT_LOCK_FAILED:
  906. case EXIT_PTYCMD_FAILED:
  907. av_type = PW_PORT_ERROR;
  908. break;
  909. case EXIT_PEER_AUTH_FAILED:
  910. case EXIT_AUTH_TOPEER_FAILED:
  911. case EXIT_NEGOTIATION_FAILED:
  912. case EXIT_CNID_AUTH_FAILED:
  913. av_type = PW_SERVICE_UNAVAILABLE;
  914. break;
  915. case EXIT_IDLE_TIMEOUT:
  916. av_type = PW_ACCT_IDLE_TIMEOUT;
  917. break;
  918. case EXIT_CALLBACK:
  919. av_type = PW_CALLBACK;
  920. break;
  921. case EXIT_CONNECT_TIME:
  922. av_type = PW_ACCT_SESSION_TIMEOUT;
  923. break;
  924. #ifdef MAXOCTETS
  925. case EXIT_TRAFFIC_LIMIT:
  926. av_type = PW_NAS_REQUEST;
  927. break;
  928. #endif
  929. default:
  930. av_type = PW_NAS_ERROR;
  931. break;
  932. }
  933. rc_avpair_add(&send, PW_ACCT_TERMINATE_CAUSE, &av_type, 0, VENDOR_NONE);
  934. hisaddr = ho->hisaddr;
  935. av_type = htonl(hisaddr);
  936. rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
  937. /* Add user specified vp's */
  938. if (rstate.avp)
  939. rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
  940. if (rstate.acctserver) {
  941. result = rc_acct_using_server(rstate.acctserver,
  942. rstate.client_port, send);
  943. } else {
  944. result = rc_acct(rstate.client_port, send);
  945. }
  946. if (result != OK_RC) {
  947. /* RADIUS server could be down so make this a warning */
  948. syslog(LOG_WARNING,
  949. "Accounting STOP failed for %s", rstate.user);
  950. }
  951. rc_avpair_free(send);
  952. }
  953. /**********************************************************************
  954. * %FUNCTION: radius_acct_interim
  955. * %ARGUMENTS:
  956. * None
  957. * %RETURNS:
  958. * Nothing
  959. * %DESCRIPTION:
  960. * Sends an interim accounting message to the RADIUS server
  961. ***********************************************************************/
  962. static void
  963. radius_acct_interim(void *ignored)
  964. {
  965. UINT4 av_type;
  966. VALUE_PAIR *send = NULL;
  967. ipcp_options *ho = &ipcp_hisoptions[0];
  968. u_int32_t hisaddr;
  969. int result;
  970. if (!rstate.initialized) {
  971. return;
  972. }
  973. if (!rstate.accounting_started) {
  974. return;
  975. }
  976. rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id,
  977. 0, VENDOR_NONE);
  978. rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE);
  979. av_type = PW_STATUS_ALIVE;
  980. rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE);
  981. av_type = PW_FRAMED;
  982. rc_avpair_add(&send, PW_SERVICE_TYPE, &av_type, 0, VENDOR_NONE);
  983. av_type = PW_PPP;
  984. rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &av_type, 0, VENDOR_NONE);
  985. av_type = PW_RADIUS;
  986. rc_avpair_add(&send, PW_ACCT_AUTHENTIC, &av_type, 0, VENDOR_NONE);
  987. /* Update link stats */
  988. update_link_stats(0);
  989. if (link_stats_valid) {
  990. link_stats_valid = 0; /* Force later code to update */
  991. av_type = link_connect_time;
  992. rc_avpair_add(&send, PW_ACCT_SESSION_TIME, &av_type, 0, VENDOR_NONE);
  993. av_type = link_stats.bytes_out;
  994. rc_avpair_add(&send, PW_ACCT_OUTPUT_OCTETS, &av_type, 0, VENDOR_NONE);
  995. av_type = link_stats.bytes_in;
  996. rc_avpair_add(&send, PW_ACCT_INPUT_OCTETS, &av_type, 0, VENDOR_NONE);
  997. av_type = link_stats.pkts_out;
  998. rc_avpair_add(&send, PW_ACCT_OUTPUT_PACKETS, &av_type, 0, VENDOR_NONE);
  999. av_type = link_stats.pkts_in;
  1000. rc_avpair_add(&send, PW_ACCT_INPUT_PACKETS, &av_type, 0, VENDOR_NONE);
  1001. }
  1002. if (*remote_number) {
  1003. rc_avpair_add(&send, PW_CALLING_STATION_ID,
  1004. remote_number, 0, VENDOR_NONE);
  1005. } else if (ipparam)
  1006. rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);
  1007. av_type = ( using_pty ? PW_VIRTUAL : ( sync_serial ? PW_SYNC : PW_ASYNC ) );
  1008. rc_avpair_add(&send, PW_NAS_PORT_TYPE, &av_type, 0, VENDOR_NONE);
  1009. hisaddr = ho->hisaddr;
  1010. av_type = htonl(hisaddr);
  1011. rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
  1012. /* Add user specified vp's */
  1013. if (rstate.avp)
  1014. rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));
  1015. if (rstate.acctserver) {
  1016. result = rc_acct_using_server(rstate.acctserver,
  1017. rstate.client_port, send);
  1018. } else {
  1019. result = rc_acct(rstate.client_port, send);
  1020. }
  1021. if (result != OK_RC) {
  1022. /* RADIUS server could be down so make this a warning */
  1023. syslog(LOG_WARNING,
  1024. "Interim accounting failed for %s", rstate.user);
  1025. }
  1026. rc_avpair_free(send);
  1027. /* Schedule another one */
  1028. TIMEOUT(radius_acct_interim, NULL, rstate.acct_interim_interval);
  1029. }
  1030. /**********************************************************************
  1031. * %FUNCTION: radius_ip_up
  1032. * %ARGUMENTS:
  1033. * opaque -- ignored
  1034. * arg -- ignored
  1035. * %RETURNS:
  1036. * Nothing
  1037. * %DESCRIPTION:
  1038. * Called when IPCP is up. We'll do a start-accounting record.
  1039. ***********************************************************************/
  1040. static void
  1041. radius_ip_up(void *opaque, int arg)
  1042. {
  1043. radius_acct_start();
  1044. }
  1045. /**********************************************************************
  1046. * %FUNCTION: radius_ip_down
  1047. * %ARGUMENTS:
  1048. * opaque -- ignored
  1049. * arg -- ignored
  1050. * %RETURNS:
  1051. * Nothing
  1052. * %DESCRIPTION:
  1053. * Called when IPCP is down. We'll do a stop-accounting record.
  1054. ***********************************************************************/
  1055. static void
  1056. radius_ip_down(void *opaque, int arg)
  1057. {
  1058. radius_acct_stop();
  1059. }
  1060. /**********************************************************************
  1061. * %FUNCTION: radius_init
  1062. * %ARGUMENTS:
  1063. * msg -- buffer of size BUF_LEN for error message
  1064. * %RETURNS:
  1065. * negative on failure; non-negative on success
  1066. * %DESCRIPTION:
  1067. * Initializes radiusclient library
  1068. ***********************************************************************/
  1069. static int
  1070. radius_init(char *msg)
  1071. {
  1072. if (rstate.initialized) {
  1073. return 0;
  1074. }
  1075. if (config_file && *config_file) {
  1076. strlcpy(rstate.config_file, config_file, MAXPATHLEN-1);
  1077. }
  1078. rstate.initialized = 1;
  1079. if (rc_read_config(rstate.config_file) != 0) {
  1080. slprintf(msg, BUF_LEN, "RADIUS: Can't read config file %s",
  1081. rstate.config_file);
  1082. return -1;
  1083. }
  1084. if (rc_read_dictionary(rc_conf_str("dictionary")) != 0) {
  1085. slprintf(msg, BUF_LEN, "RADIUS: Can't read dictionary file %s",
  1086. rc_conf_str("dictionary"));
  1087. return -1;
  1088. }
  1089. if (rc_read_mapfile(rc_conf_str("mapfile")) != 0) {
  1090. slprintf(msg, BUF_LEN, "RADIUS: Can't read map file %s",
  1091. rc_conf_str("mapfile"));
  1092. return -1;
  1093. }
  1094. /* Add av pairs saved during option parsing */
  1095. while (avpopt) {
  1096. struct avpopt *n = avpopt->next;
  1097. rc_avpair_parse(avpopt->vpstr, &rstate.avp);
  1098. free(avpopt->vpstr);
  1099. free(avpopt);
  1100. avpopt = n;
  1101. }
  1102. return 0;
  1103. }
  1104. /**********************************************************************
  1105. * %FUNCTION: get_client_port
  1106. * %ARGUMENTS:
  1107. * ifname -- PPP interface name (e.g. "ppp7")
  1108. * %RETURNS:
  1109. * The NAS port number (e.g. 7)
  1110. * %DESCRIPTION:
  1111. * Extracts the port number from the interface name
  1112. ***********************************************************************/
  1113. static int
  1114. get_client_port(char *ifname)
  1115. {
  1116. int port;
  1117. if (sscanf(ifname, "ppp%d", &port) == 1) {
  1118. return port;
  1119. }
  1120. return rc_map2id(ifname);
  1121. }
  1122. /**********************************************************************
  1123. * %FUNCTION: radius_allowed_address
  1124. * %ARGUMENTS:
  1125. * addr -- IP address
  1126. * %RETURNS:
  1127. * 1 if we're allowed to use that IP address; 0 if not; -1 if we do
  1128. * not know.
  1129. ***********************************************************************/
  1130. static int
  1131. radius_allowed_address(u_int32_t addr)
  1132. {
  1133. ipcp_options *wo = &ipcp_wantoptions[0];
  1134. if (!rstate.choose_ip) {
  1135. /* If RADIUS server said any address is OK, then fine... */
  1136. if (rstate.any_ip_addr_ok) {
  1137. return 1;
  1138. }
  1139. /* Sigh... if an address was supplied for remote host in pppd
  1140. options, it has to match that. */
  1141. if (wo->hisaddr != 0 && wo->hisaddr == addr) {
  1142. return 1;
  1143. }
  1144. return 0;
  1145. }
  1146. if (addr == rstate.ip_addr) return 1;
  1147. return 0;
  1148. }
  1149. /* Useful for other plugins */
  1150. char *radius_logged_in_user(void)
  1151. {
  1152. return rstate.user;
  1153. }