18ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project/* 28ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 38ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* radrealms.c 48ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 58ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* A pppd plugin which is stacked on top of radius.so. This plugin 68ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* allows selection of alternate set of servers based on the user's realm. 78ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 88ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Author: Ben McKeegan ben@netservers.co.uk 98ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* Copyright (C) 2002 Netservers 118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* This plugin may be distributed according to the terms of the GNU 138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* General Public License, version 2 or (at your option) any later version. 148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project* 158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project*/ 168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic char const RCSID[] = 188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project "$Id: radrealms.c,v 1.2 2004/11/14 07:26:26 paulus Exp $"; 198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "pppd.h" 218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include "radiusclient.h" 228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdio.h> 238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <string.h> 248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project#include <stdlib.h> 258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar pppd_version[] = VERSION; 278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectchar radrealms_config[MAXPATHLEN] = "/etc/radiusclient/realms"; 298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic option_t Options[] = { 311286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley { "realms-config-file", o_string, &radrealms_config, 321286c078a4b93695b3812e8c7fe7918c28ea18b4Adam Langley "Configuration file for RADIUS realms", OPT_STATIC, NULL, MAXPATHLEN }, 338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project { NULL } 348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project}; 358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectextern void (*radius_pre_auth_hook)(char const *user, 378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SERVER **authserver, 388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SERVER **acctserver); 398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectstatic void 418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectlookup_realm(char const *user, 428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SERVER **authserver, 438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SERVER **acctserver) 448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char *realm; 468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project FILE *fd; 478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project SERVER *accts, *auths, *s; 488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project char buffer[512], *p; 498ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project int line = 0; 508ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 518ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auths = (SERVER *) malloc(sizeof(SERVER)); 528ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project auths->max = 0; 538ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project accts = (SERVER *) malloc(sizeof(SERVER)); 548ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project accts->max = 0; 558ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 568ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project realm = strrchr(user, '@'); 578ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 588ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (realm) { 598ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("Looking up servers for realm '%s'", realm); 608ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else { 618ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("Looking up servers for DEFAULT realm"); 628ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 638ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (realm) { 648ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (*(++realm) == '\0') { 658ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project realm = NULL; 668ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 678ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 688ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 698ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((fd = fopen(radrealms_config, "r")) == NULL) { 708ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("cannot open %s", radrealms_config); 718ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 728ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 738ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("Reading %s", radrealms_config); 748ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 758ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project while ((fgets(buffer, sizeof(buffer), fd) != NULL)) { 768ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project line++; 778ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 788ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((*buffer == '\n') || (*buffer == '#') || (*buffer == '\0')) 798ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project continue; 808ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 818ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project buffer[strlen(buffer)-1] = '\0'; 828ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 838ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project p = strtok(buffer, "\t "); 848ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 858ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (p == NULL || (strcmp(p, "authserver") !=0 868ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project && strcmp(p, "acctserver"))) { 878ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fclose(fd); 888ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("%s: invalid line %d: %s", radrealms_config, 898ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project line, buffer); 908ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 918ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 928ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("Parsing '%s' entry:", p); 938ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project s = auths; 948ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (p[1] == 'c') { 958ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project s = accts; 968ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 978ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (s->max >= SERVER_MAX) 988ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project continue; 998ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1008ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((p = strtok(NULL, "\t ")) == NULL) { 1018ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fclose(fd); 1028ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("%s: realm name missing on line %d: %s", 1038ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project radrealms_config, line, buffer); 1048ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 1058ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1068ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1078ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((realm != NULL && strcmp(p, realm) == 0) || 1088ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project (realm == NULL && strcmp(p, "DEFAULT") == 0) ) { 1098ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info(" - Matched realm %s", p); 1108ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((p = strtok(NULL, ":")) == NULL) { 1118ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fclose(fd); 1128ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("%s: server address missing on line %d: %s", 1138ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project radrealms_config, line, buffer); 1148ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 1158ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1168ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project s->name[s->max] = strdup(p); 1178ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info(" - Address is '%s'",p); 1188ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if ((p = strtok(NULL, "\t ")) == NULL) { 1198ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fclose(fd); 1208ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project option_error("%s: server port missing on line %d: %s", 1218ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project radrealms_config, line, buffer); 1228ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 1238ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1248ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project s->port[s->max] = atoi(p); 1258ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info(" - Port is '%d'", s->port[s->max]); 1268ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project s->max++; 1278ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } else 1288ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info(" - Skipping realm '%s'", p); 1298ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project } 1308ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project fclose(fd); 1318ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1328ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (accts->max) 1338ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *acctserver = accts; 1348ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1358ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project if (auths->max) 1368ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project *authserver = auths; 1378ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1388ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project return; 1398ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 1408ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1418ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectvoid 1428ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Projectplugin_init(void) 1438ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project{ 1448ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project radius_pre_auth_hook = lookup_realm; 1458ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project 1468ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project add_options(Options); 1478ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project info("RADIUS Realms plugin initialized."); 1488ad0dd2a5c5f23cd210aedba72a43e48026e7436The Android Open Source Project} 149