From 920f339ee0360ae3f2069fa04c25c1ae979fbe65 Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 7 May 2002 10:06:54 +0000 Subject: Understand the Session-Timeout RADIUS attribute Store the Filter-Id attribute (we don't do anything with it yet) Submitted mostly by: andrew pavlov --- usr.sbin/ppp/bundle.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++-- usr.sbin/ppp/bundle.h | 12 +++++++++ usr.sbin/ppp/ppp.8.m4 | 5 ++++ usr.sbin/ppp/radius.c | 21 +++++++++++++-- usr.sbin/ppp/radius.h | 2 ++ 5 files changed, 109 insertions(+), 4 deletions(-) (limited to 'usr.sbin/ppp') diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c index 137888b..bbec25d 100644 --- a/usr.sbin/ppp/bundle.c +++ b/usr.sbin/ppp/bundle.c @@ -227,6 +227,13 @@ bundle_LinkAdded(struct bundle *bundle, struct datalink *dl) if (dl->state == DATALINK_OPEN) bundle->phys_type.open |= dl->physical->type; +#ifndef NORADIUS + if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) + != bundle->phys_type.open && bundle->session.timer.state == TIMER_STOPPED) + if (bundle->radius.sessiontime) + bundle_StartSessionTimer(bundle, 0); +#endif + if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) != bundle->phys_type.open && bundle->idle.timer.state == TIMER_STOPPED) /* We may need to start our idle timer */ @@ -246,8 +253,13 @@ bundle_LinksRemoved(struct bundle *bundle) mp_CheckAutoloadTimer(&bundle->ncp.mp); if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) - == bundle->phys_type.open) + == bundle->phys_type.open) { +#ifndef NORADIUS + if (bundle->radius.sessiontime) + bundle_StopSessionTimer(bundle); +#endif bundle_StopIdleTimer(bundle); + } } static void @@ -274,6 +286,10 @@ bundle_LayerUp(void *v, struct fsm *fp) if (ncp_LayersOpen(&fp->bundle->ncp) == 1) { bundle_CalculateBandwidth(fp->bundle); time(&bundle->upat); +#ifndef NORADIUS + if (bundle->radius.sessiontime) + bundle_StartSessionTimer(bundle, 0); +#endif bundle_StartIdleTimer(bundle, 0); mp_CheckAutoloadTimer(&fp->bundle->ncp.mp); } @@ -300,6 +316,10 @@ bundle_LayerDown(void *v, struct fsm *fp) if (isncp(fp->proto)) { if (ncp_LayersOpen(&fp->bundle->ncp) == 0) { +#ifndef NORADIUS + if (bundle->radius.sessiontime) + bundle_StopSessionTimer(bundle); +#endif bundle_StopIdleTimer(bundle); bundle->upat = 0; mp_StopAutoloadTimer(&bundle->ncp.mp); @@ -399,6 +419,10 @@ bundle_Close(struct bundle *bundle, const char *name, int how) } if (!others_active) { +#ifndef NORADIUS + if (bundle->radius.sessiontime) + bundle_StopSessionTimer(bundle); +#endif bundle_StopIdleTimer(bundle); if (ncp_LayersUnfinished(&bundle->ncp)) ncp_Close(&bundle->ncp); @@ -942,6 +966,10 @@ bundle_LinkClosed(struct bundle *bundle, struct datalink *dl) ncp2initial(&bundle->ncp); mp_Down(&bundle->ncp.mp); bundle_NewPhase(bundle, PHASE_DEAD); +#ifndef NORADIUS + if (bundle->radius.sessiontime) + bundle_StopSessionTimer(bundle); +#endif bundle_StopIdleTimer(bundle); } } @@ -1184,6 +1212,47 @@ bundle_RemainingIdleTime(struct bundle *bundle) return -1; } +#ifndef NORADIUS + +static void +bundle_SessionTimeout(void *v) +{ + struct bundle *bundle = (struct bundle *)v; + + log_Printf(LogPHASE, "Session-Timeout timer expired\n"); + bundle_StopSessionTimer(bundle); + bundle_Close(bundle, NULL, CLOSE_STAYDOWN); +} + +void +bundle_StartSessionTimer(struct bundle *bundle, unsigned secs) +{ + timer_Stop(&bundle->session.timer); + if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) != + bundle->phys_type.open && bundle->radius.sessiontime) { + time_t now = time(NULL); + + if (secs == 0) + secs = bundle->radius.sessiontime; + + bundle->session.timer.func = bundle_SessionTimeout; + bundle->session.timer.name = "session"; + bundle->session.timer.load = secs * SECTICKS; + bundle->session.timer.arg = bundle; + timer_Start(&bundle->session.timer); + bundle->session.done = now + secs; + } +} + +void +bundle_StopSessionTimer(struct bundle *bundle) +{ + timer_Stop(&bundle->session.timer); + bundle->session.done = 0; +} + +#endif + int bundle_IsDead(struct bundle *bundle) { @@ -1825,7 +1894,7 @@ bundle_CalculateBandwidth(struct bundle *bundle) } } - if(bundle->bandwidth == 0) + if (bundle->bandwidth == 0) bundle->bandwidth = 115200; /* Shrug */ if (bundle->ncp.mp.active) { diff --git a/usr.sbin/ppp/bundle.h b/usr.sbin/ppp/bundle.h index d8c056a..b2cb6f0 100644 --- a/usr.sbin/ppp/bundle.h +++ b/usr.sbin/ppp/bundle.h @@ -127,6 +127,13 @@ struct bundle { time_t done; } idle; +#ifndef NORADIUS + struct { + struct pppTimer timer; + time_t done; + } session; +#endif + struct { int fd; /* write status here */ } notify; @@ -163,6 +170,11 @@ extern void bundle_StopIdleTimer(struct bundle *); extern int bundle_IsDead(struct bundle *); extern struct datalink *bundle2datalink(struct bundle *, const char *); +#ifndef NORADIUS +extern void bundle_StartSessionTimer(struct bundle *, unsigned secs); +extern void bundle_StopSessionTimer(struct bundle *); +#endif + extern void bundle_RegisterDescriptor(struct bundle *, struct fdescriptor *); extern void bundle_UnRegisterDescriptor(struct bundle *, struct fdescriptor *); diff --git a/usr.sbin/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4 index 79687c6..26a2f99 100644 --- a/usr.sbin/ppp/ppp.8.m4 +++ b/usr.sbin/ppp/ppp.8.m4 @@ -5278,6 +5278,8 @@ If the received compression type is will request VJ compression during IPCP negotiations despite any .Dq disable vj configuration command. +.It RAD_FILTER_ID +This attribute is stored but not yet used. .It RAD_FRAMED_ROUTE The received string is expected to be in the format .Ar dest Ns Op / Ns Ar bits @@ -5324,6 +5326,9 @@ or .Dv HISADDR keywords. .Pp +.It RAD_SESSION_TIMEOUT +If supplied, the client connection is closed after the given number of +seconds. .El Values received from the RADIUS server may be viewed using .Dq show bundle . diff --git a/usr.sbin/ppp/radius.c b/usr.sbin/ppp/radius.c index 1a49011..0d0bbae 100644 --- a/usr.sbin/ppp/radius.c +++ b/usr.sbin/ppp/radius.c @@ -167,6 +167,21 @@ radius_Process(struct radius *r, int got) log_Printf(LogPHASE, " IP %s\n", inet_ntoa(r->ip)); break; + case RAD_FILTER_ID: + free(r->filterid); + if ((r->filterid = rad_cvt_string(data, len)) == NULL) { + log_Printf(LogERROR, "rad_cvt_string: %s\n", rad_strerror(r->cx.rad)); + rad_close(r->cx.rad); + return; + } + log_Printf(LogPHASE, " Filter \"%s\"\n", r->filterid); + break; + + case RAD_SESSION_TIMEOUT: + r->sessiontime = rad_cvt_int(data); + log_Printf(LogPHASE, " Session-Timeout %lu\n", r->sessiontime); + break; + case RAD_FRAMED_IP_NETMASK: r->mask = rad_cvt_addr(data); log_Printf(LogPHASE, " Netmask %s\n", inet_ntoa(r->mask)); @@ -365,6 +380,8 @@ radius_Destroy(struct radius *r) log_Printf(LogDEBUG, "Radius: radius_Destroy\n"); timer_Stop(&r->cx.timer); route_DeleteAll(&r->routes); + free(r->filterid); + r->filterid = NULL; if (r->cx.fd != -1) { r->cx.fd = -1; rad_close(r->cx.rad); @@ -463,7 +480,7 @@ radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name, setttyent(); for (slot = 1; (ttyp = getttyent()); ++slot) if (!strcmp(ttyp->ty_name, authp->physical->name.base)) { - if(rad_put_int(r->cx.rad, RAD_NAS_PORT, slot) != 0) { + if (rad_put_int(r->cx.rad, RAD_NAS_PORT, slot) != 0) { log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", rad_strerror(r->cx.rad)); rad_close(r->cx.rad); @@ -593,7 +610,7 @@ radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl, setttyent(); for (slot = 1; (ttyp = getttyent()); ++slot) if (!strcmp(ttyp->ty_name, dl->physical->name.base)) { - if(rad_put_int(r->cx.rad, RAD_NAS_PORT, slot) != 0) { + if (rad_put_int(r->cx.rad, RAD_NAS_PORT, slot) != 0) { log_Printf(LogERROR, "rad_put: rad_put_string: %s\n", rad_strerror(r->cx.rad)); rad_close(r->cx.rad); diff --git a/usr.sbin/ppp/radius.h b/usr.sbin/ppp/radius.h index 152df3f..1b3d188 100644 --- a/usr.sbin/ppp/radius.h +++ b/usr.sbin/ppp/radius.h @@ -39,6 +39,8 @@ struct radius { struct in_addr ip; /* FRAMED IP */ struct in_addr mask; /* FRAMED Netmask */ unsigned long mtu; /* FRAMED MTU */ + unsigned long sessiontime; /* Session-Timeout */ + char *filterid; /* FRAMED Filter Id */ struct sticky_route *routes; /* FRAMED Routes */ struct { char file[PATH_MAX]; /* Radius config file */ -- cgit v1.1