Skip to content

Commit

Permalink
First version in CVS is radiusplugin_v2.0b.
Browse files Browse the repository at this point in the history
  • Loading branch information
ralfluebben committed Jul 21, 2007
1 parent 1f4b043 commit 181bf81
Show file tree
Hide file tree
Showing 56 changed files with 23,687 additions and 0 deletions.
494 changes: 494 additions & 0 deletions AccountingProcess.cpp

Large diffs are not rendered by default.

39 changes: 39 additions & 0 deletions AccountingProcess.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* radiusplugin -- An OpenVPN plugin for do radius authentication
* and accounting.
*
* Copyright (C) 2005 EWE TEL GmbH/Ralf Luebben <ralfluebben@gmx.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef _ACCOUNTINGPROCESS_H_
#define _ACCOUNTINGPROCESS_H_
#include <sys/types.h>
#include <sys/stat.h>
#include "PluginContext.h"
#include "UserAcct.h"
#include "AcctScheduler.h"
#include "radiusplugin.h"

/** The class represents the background process for accounting. */
class AccountingProcess
{
public:
void Accounting(PluginContext *);
int callVsaScript(PluginContext *, User *, unsigned int , unsigned int);
};

#endif //_ACCOUNTINGPROCESS_H_
257 changes: 257 additions & 0 deletions AcctScheduler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
/*
* radiusplugin -- An OpenVPN plugin for do radius authentication
* and accounting.
*
* Copyright (C) 2005 EWE TEL GmbH/Ralf Luebben <ralfluebben@gmx.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "AcctScheduler.h"
#include "PluginContext.h"
#include "RadiusClass/RadiusConfig.h"
#include "Config.h"
#include "radiusplugin.h"




using namespace std;

/** The constructor of the class.
* Nothing happens here.
*/

AcctScheduler::AcctScheduler()
{
}

/**The destructor of the class.
* The user lists are cleared here.
*/
AcctScheduler::~AcctScheduler()
{
activeuserlist.clear();
passiveuserlist.clear();
}

/** The method adds an user to the user lists. An user with an acct interim
* interval is added to the activeuserlist, an user
* without this interval is added to passiveuserlist.
* @param user A pointer to an object from the class UserAcct.
*/
void AcctScheduler::addUser(UserAcct *user)
{
if (user->getAcctInterimInterval()==0)
{

this->passiveuserlist.insert(make_pair(user->getKey(),*user));
}
else
{
this->activeuserlist.insert(make_pair(user->getKey(),*user));
}
}

/** The method deletes an user from the user lists. Before
* the user is deleted the status file is parsed for the sent and received bytes
* and the stop accouting ticket is send to the server.
* @param context The plugin context as an object from the class PluginContext.
* @param user A pointer to an object from the class UserAcct
*/
void AcctScheduler::delUser(PluginContext * context, UserAcct *user)
{
uint64_t bytesin=0, bytesout=0;

//get the sent and received bytes
this->parseStatusFile(context, &bytesin, &bytesout,user->getKey().c_str());

user->setBytesIn(bytesin & 0xFFFFFFFF);
user->setBytesOut(bytesout & 0xFFFFFFFF);
user->setGigaIn(bytesin >> 32);
user->setGigaOut(bytesout >> 32);

if (DEBUG (context->getVerbosity()))
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Got accouting data from file, CN: " << user->getCommonname() << " in: " << user->getBytesIn() << " out: " << user->getBytesOut() << ".\n";


//send the stop ticket
if (user->sendStopPacket(context)==0)
{
if (DEBUG (context->getVerbosity()))
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Stop packet was sent. CN: " << user->getCommonname() << ".\n";
}
else
{
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Error on sending stop packet.";
}

if (user->getAcctInterimInterval()==0)
{
passiveuserlist.erase(user->getKey());
}
else
{

activeuserlist.erase(user->getKey());
}

}


/** The method deletes all users from the user lists. Before
* the user is deleted the status file is parsed for the sent and received bytes
* and the stop accouting ticket is send to the server.
* @param context The plugin context as an object from the class PluginContext.
*/
void AcctScheduler::delallUsers(PluginContext * context)
{
map<string, UserAcct>::iterator iter1, iter2;
if (DEBUG (context->getVerbosity()))
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Delete all users.";
iter1=activeuserlist.begin();
iter2=activeuserlist.end();


while (iter1!=iter2)
{
this->delUser(context,&(iter1->second));
iter1++;
}

}

/** The accouting method. When the method is called it
* searches for users in activeuserlist for users who need an update.
* If a user is found the sent and received bytes are read from the
* OpenVpn status file.
* @param context The plugin context as an object from the class PluginContext.
*/

void AcctScheduler::doAccounting(PluginContext * context)
{
time_t t;

uint64_t bytesin=0, bytesout=0;
map<string, UserAcct>::iterator iter1, iter2;


iter1=activeuserlist.begin();
iter2=activeuserlist.end();


while (iter1!=iter2)
{
//get the time
time(&t);
//if the user needs an update
if ( t>=iter1->second.getNextUpdate())
{
if (DEBUG (context->getVerbosity()))
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Scheduler: Update for User " << iter1->second.getUsername() << ".\n";

this->parseStatusFile(context, &bytesin, &bytesout,iter1->second.getKey().c_str());
iter1->second.setBytesIn(bytesin & 0xFFFFFFFF);
iter1->second.setBytesOut(bytesout & 0xFFFFFFFF);
iter1->second.setGigaIn(bytesin >> 32);
iter1->second.setGigaOut(bytesout >> 32);
iter1->second.sendUpdatePacket(context);

if (DEBUG (context->getVerbosity()))
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Scheduler: Update packet for User " << iter1->second.getUsername() << " was send.\n";

//calculate the next update
iter1->second.setNextUpdate(iter1->second.getNextUpdate()+iter1->second.getAcctInterimInterval());
}
iter1++;
}
}

/**The method parses the status file for accounting information. It reads the bytes sent
* and received from the status file. It finds the values about the commonname. The method will
* only work if there are no changes in the structure of the status file.
* The method is test with OpenVpn 2.0.
* @param context The plugin context as an object from the class PluginContext.
* @param bytesin An int pointer for the received bytes.
* @param bytesout An int pointer for the sent bytes.
* @param key A key which identifies the row in the statusfile, it looks like: "commonname,ip:port".
*/
void AcctScheduler::parseStatusFile(PluginContext *context, uint64_t *bytesin, uint64_t *bytesout, string key)
{
char line[512], newline[512];
memset(newline, 0, 512);

//open the status file to read
ifstream file(context->conf.getStatusFile().c_str(), ios::in);

if (file.is_open())
{
if (DEBUG (context->getVerbosity()))
fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND ACCT: Scheduler: Read Statusfile.\n");

//find the key, is delimited with a ',' from the informations

//loop until the name is found, there is no delimiter, the string
//"ROUTING TABLE" is found or EOF

do
{
file.getline(line, 512);

}
while (line!=NULL && strncmp(line,key.c_str(),key.length())!=0 && strcmp(line,"ROUTING TABLE")!=0 && file.eof()==false);


//the information is after the next delimiters
if (line!=NULL && strncmp(line,key.c_str(),key.length())==0)
{
memcpy(newline, line+key.length(), strlen(line)-key.length()+1);
*bytesin=strtoull(strtok(newline,","),NULL,10);
*bytesout=strtoull(strtok(NULL,","),NULL,10);
}
else
{

cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: No accounting data was found for "<< key <<".\n";

}
file.close();
}
else
{
cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Statusfile "<< context->conf.getStatusFile() <<" could not opened.\n";
}
}

/** The method finds an user.
* @param key The commonname of the user to find.
* @return A poniter to an object of the class UserAcct.
*/
UserAcct * AcctScheduler::findUser(string key)
{
map<string, UserAcct>::iterator iter;
iter=activeuserlist.find(key);
if (iter!=activeuserlist.end())
{
return &(iter->second);
}
iter=passiveuserlist.find(key);
if (iter!=passiveuserlist.end())
{
return &(iter->second);
}

return NULL;
}
68 changes: 68 additions & 0 deletions AcctScheduler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* radiusplugin -- An OpenVPN plugin for do radius authentication
* and accounting.
*
* Copyright (C) 2005 EWE TEL GmbH/Ralf Luebben <ralfluebben@gmx.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef _ACCT_SCHEDULER_H_
#define _ACCT_SCHEDULER_H_

#include <ctime>
#include <cstdlib>
#include <cstring>
#include <cstdio>

#include <iostream>
#include <map>
#include <fstream>
#include "UserAcct.h"

using std::map;

/**The class is a scheduler for accounting radius users. It calculates the
* accounting interval if the ACCT-INTERIM-INTERVAL was present in the
* authentication response from the radius server.
* The start and stop accounting ticket are always sent for a user
* which is added to the scheduler.
* For the update and stop accounting ticket the sent and received bytes
* are read out of the OpenVpn status file.
*/


class AcctScheduler
{

private:
map<string, UserAcct> activeuserlist; /**<The map for user with a acct interim interval.*/
map<string, UserAcct> passiveuserlist; /**<The map for user without a acct interim interval.*/

public:
AcctScheduler();
~AcctScheduler();

void addUser(UserAcct *user);
void delUser(PluginContext * context, UserAcct *user);
void delallUsers(PluginContext * context);

UserAcct * findUser(string);

void doAccounting(PluginContext *);

void parseStatusFile(PluginContext *, uint64_t *, uint64_t *,string);
};
#endif //_ACCT_SCHEDULER_H_
Loading

0 comments on commit 181bf81

Please sign in to comment.