Skip to content

Commit 181bf81

Browse files
author
ralfluebben
committed
First version in CVS is radiusplugin_v2.0b.
1 parent 1f4b043 commit 181bf81

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+23687
-0
lines changed

AccountingProcess.cpp

+494
Large diffs are not rendered by default.

AccountingProcess.h

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* radiusplugin -- An OpenVPN plugin for do radius authentication
3+
* and accounting.
4+
*
5+
* Copyright (C) 2005 EWE TEL GmbH/Ralf Luebben <[email protected]>
6+
*
7+
* This program is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20+
*/
21+
22+
#ifndef _ACCOUNTINGPROCESS_H_
23+
#define _ACCOUNTINGPROCESS_H_
24+
#include <sys/types.h>
25+
#include <sys/stat.h>
26+
#include "PluginContext.h"
27+
#include "UserAcct.h"
28+
#include "AcctScheduler.h"
29+
#include "radiusplugin.h"
30+
31+
/** The class represents the background process for accounting. */
32+
class AccountingProcess
33+
{
34+
public:
35+
void Accounting(PluginContext *);
36+
int callVsaScript(PluginContext *, User *, unsigned int , unsigned int);
37+
};
38+
39+
#endif //_ACCOUNTINGPROCESS_H_

AcctScheduler.cpp

+257
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/*
2+
* radiusplugin -- An OpenVPN plugin for do radius authentication
3+
* and accounting.
4+
*
5+
* Copyright (C) 2005 EWE TEL GmbH/Ralf Luebben <[email protected]>
6+
*
7+
* This program is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20+
*/
21+
22+
#include "AcctScheduler.h"
23+
#include "PluginContext.h"
24+
#include "RadiusClass/RadiusConfig.h"
25+
#include "Config.h"
26+
#include "radiusplugin.h"
27+
28+
29+
30+
31+
using namespace std;
32+
33+
/** The constructor of the class.
34+
* Nothing happens here.
35+
*/
36+
37+
AcctScheduler::AcctScheduler()
38+
{
39+
}
40+
41+
/**The destructor of the class.
42+
* The user lists are cleared here.
43+
*/
44+
AcctScheduler::~AcctScheduler()
45+
{
46+
activeuserlist.clear();
47+
passiveuserlist.clear();
48+
}
49+
50+
/** The method adds an user to the user lists. An user with an acct interim
51+
* interval is added to the activeuserlist, an user
52+
* without this interval is added to passiveuserlist.
53+
* @param user A pointer to an object from the class UserAcct.
54+
*/
55+
void AcctScheduler::addUser(UserAcct *user)
56+
{
57+
if (user->getAcctInterimInterval()==0)
58+
{
59+
60+
this->passiveuserlist.insert(make_pair(user->getKey(),*user));
61+
}
62+
else
63+
{
64+
this->activeuserlist.insert(make_pair(user->getKey(),*user));
65+
}
66+
}
67+
68+
/** The method deletes an user from the user lists. Before
69+
* the user is deleted the status file is parsed for the sent and received bytes
70+
* and the stop accouting ticket is send to the server.
71+
* @param context The plugin context as an object from the class PluginContext.
72+
* @param user A pointer to an object from the class UserAcct
73+
*/
74+
void AcctScheduler::delUser(PluginContext * context, UserAcct *user)
75+
{
76+
uint64_t bytesin=0, bytesout=0;
77+
78+
//get the sent and received bytes
79+
this->parseStatusFile(context, &bytesin, &bytesout,user->getKey().c_str());
80+
81+
user->setBytesIn(bytesin & 0xFFFFFFFF);
82+
user->setBytesOut(bytesout & 0xFFFFFFFF);
83+
user->setGigaIn(bytesin >> 32);
84+
user->setGigaOut(bytesout >> 32);
85+
86+
if (DEBUG (context->getVerbosity()))
87+
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Got accouting data from file, CN: " << user->getCommonname() << " in: " << user->getBytesIn() << " out: " << user->getBytesOut() << ".\n";
88+
89+
90+
//send the stop ticket
91+
if (user->sendStopPacket(context)==0)
92+
{
93+
if (DEBUG (context->getVerbosity()))
94+
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Stop packet was sent. CN: " << user->getCommonname() << ".\n";
95+
}
96+
else
97+
{
98+
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Error on sending stop packet.";
99+
}
100+
101+
if (user->getAcctInterimInterval()==0)
102+
{
103+
passiveuserlist.erase(user->getKey());
104+
}
105+
else
106+
{
107+
108+
activeuserlist.erase(user->getKey());
109+
}
110+
111+
}
112+
113+
114+
/** The method deletes all users from the user lists. Before
115+
* the user is deleted the status file is parsed for the sent and received bytes
116+
* and the stop accouting ticket is send to the server.
117+
* @param context The plugin context as an object from the class PluginContext.
118+
*/
119+
void AcctScheduler::delallUsers(PluginContext * context)
120+
{
121+
map<string, UserAcct>::iterator iter1, iter2;
122+
if (DEBUG (context->getVerbosity()))
123+
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Delete all users.";
124+
iter1=activeuserlist.begin();
125+
iter2=activeuserlist.end();
126+
127+
128+
while (iter1!=iter2)
129+
{
130+
this->delUser(context,&(iter1->second));
131+
iter1++;
132+
}
133+
134+
}
135+
136+
/** The accouting method. When the method is called it
137+
* searches for users in activeuserlist for users who need an update.
138+
* If a user is found the sent and received bytes are read from the
139+
* OpenVpn status file.
140+
* @param context The plugin context as an object from the class PluginContext.
141+
*/
142+
143+
void AcctScheduler::doAccounting(PluginContext * context)
144+
{
145+
time_t t;
146+
147+
uint64_t bytesin=0, bytesout=0;
148+
map<string, UserAcct>::iterator iter1, iter2;
149+
150+
151+
iter1=activeuserlist.begin();
152+
iter2=activeuserlist.end();
153+
154+
155+
while (iter1!=iter2)
156+
{
157+
//get the time
158+
time(&t);
159+
//if the user needs an update
160+
if ( t>=iter1->second.getNextUpdate())
161+
{
162+
if (DEBUG (context->getVerbosity()))
163+
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Scheduler: Update for User " << iter1->second.getUsername() << ".\n";
164+
165+
this->parseStatusFile(context, &bytesin, &bytesout,iter1->second.getKey().c_str());
166+
iter1->second.setBytesIn(bytesin & 0xFFFFFFFF);
167+
iter1->second.setBytesOut(bytesout & 0xFFFFFFFF);
168+
iter1->second.setGigaIn(bytesin >> 32);
169+
iter1->second.setGigaOut(bytesout >> 32);
170+
iter1->second.sendUpdatePacket(context);
171+
172+
if (DEBUG (context->getVerbosity()))
173+
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Scheduler: Update packet for User " << iter1->second.getUsername() << " was send.\n";
174+
175+
//calculate the next update
176+
iter1->second.setNextUpdate(iter1->second.getNextUpdate()+iter1->second.getAcctInterimInterval());
177+
}
178+
iter1++;
179+
}
180+
}
181+
182+
/**The method parses the status file for accounting information. It reads the bytes sent
183+
* and received from the status file. It finds the values about the commonname. The method will
184+
* only work if there are no changes in the structure of the status file.
185+
* The method is test with OpenVpn 2.0.
186+
* @param context The plugin context as an object from the class PluginContext.
187+
* @param bytesin An int pointer for the received bytes.
188+
* @param bytesout An int pointer for the sent bytes.
189+
* @param key A key which identifies the row in the statusfile, it looks like: "commonname,ip:port".
190+
*/
191+
void AcctScheduler::parseStatusFile(PluginContext *context, uint64_t *bytesin, uint64_t *bytesout, string key)
192+
{
193+
char line[512], newline[512];
194+
memset(newline, 0, 512);
195+
196+
//open the status file to read
197+
ifstream file(context->conf.getStatusFile().c_str(), ios::in);
198+
199+
if (file.is_open())
200+
{
201+
if (DEBUG (context->getVerbosity()))
202+
fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND ACCT: Scheduler: Read Statusfile.\n");
203+
204+
//find the key, is delimited with a ',' from the informations
205+
206+
//loop until the name is found, there is no delimiter, the string
207+
//"ROUTING TABLE" is found or EOF
208+
209+
do
210+
{
211+
file.getline(line, 512);
212+
213+
}
214+
while (line!=NULL && strncmp(line,key.c_str(),key.length())!=0 && strcmp(line,"ROUTING TABLE")!=0 && file.eof()==false);
215+
216+
217+
//the information is after the next delimiters
218+
if (line!=NULL && strncmp(line,key.c_str(),key.length())==0)
219+
{
220+
memcpy(newline, line+key.length(), strlen(line)-key.length()+1);
221+
*bytesin=strtoull(strtok(newline,","),NULL,10);
222+
*bytesout=strtoull(strtok(NULL,","),NULL,10);
223+
}
224+
else
225+
{
226+
227+
cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: No accounting data was found for "<< key <<".\n";
228+
229+
}
230+
file.close();
231+
}
232+
else
233+
{
234+
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Statusfile "<< context->conf.getStatusFile() <<" could not opened.\n";
235+
}
236+
}
237+
238+
/** The method finds an user.
239+
* @param key The commonname of the user to find.
240+
* @return A poniter to an object of the class UserAcct.
241+
*/
242+
UserAcct * AcctScheduler::findUser(string key)
243+
{
244+
map<string, UserAcct>::iterator iter;
245+
iter=activeuserlist.find(key);
246+
if (iter!=activeuserlist.end())
247+
{
248+
return &(iter->second);
249+
}
250+
iter=passiveuserlist.find(key);
251+
if (iter!=passiveuserlist.end())
252+
{
253+
return &(iter->second);
254+
}
255+
256+
return NULL;
257+
}

AcctScheduler.h

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* radiusplugin -- An OpenVPN plugin for do radius authentication
3+
* and accounting.
4+
*
5+
* Copyright (C) 2005 EWE TEL GmbH/Ralf Luebben <[email protected]>
6+
*
7+
* This program is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20+
*/
21+
22+
#ifndef _ACCT_SCHEDULER_H_
23+
#define _ACCT_SCHEDULER_H_
24+
25+
#include <ctime>
26+
#include <cstdlib>
27+
#include <cstring>
28+
#include <cstdio>
29+
30+
#include <iostream>
31+
#include <map>
32+
#include <fstream>
33+
#include "UserAcct.h"
34+
35+
using std::map;
36+
37+
/**The class is a scheduler for accounting radius users. It calculates the
38+
* accounting interval if the ACCT-INTERIM-INTERVAL was present in the
39+
* authentication response from the radius server.
40+
* The start and stop accounting ticket are always sent for a user
41+
* which is added to the scheduler.
42+
* For the update and stop accounting ticket the sent and received bytes
43+
* are read out of the OpenVpn status file.
44+
*/
45+
46+
47+
class AcctScheduler
48+
{
49+
50+
private:
51+
map<string, UserAcct> activeuserlist; /**<The map for user with a acct interim interval.*/
52+
map<string, UserAcct> passiveuserlist; /**<The map for user without a acct interim interval.*/
53+
54+
public:
55+
AcctScheduler();
56+
~AcctScheduler();
57+
58+
void addUser(UserAcct *user);
59+
void delUser(PluginContext * context, UserAcct *user);
60+
void delallUsers(PluginContext * context);
61+
62+
UserAcct * findUser(string);
63+
64+
void doAccounting(PluginContext *);
65+
66+
void parseStatusFile(PluginContext *, uint64_t *, uint64_t *,string);
67+
};
68+
#endif //_ACCT_SCHEDULER_H_

0 commit comments

Comments
 (0)