From 8f18e24717710d3e02aa240366a2084875f54a9d Mon Sep 17 00:00:00 2001 From: ralfluebben Date: Sun, 15 Feb 2009 13:42:25 +0000 Subject: [PATCH] *** empty log message *** --- AccountingProcess.cpp | 58 +- AcctScheduler.cpp | 18 +- AuthenticationProcess.cpp | 18 +- ChangeLog | 5 + Makefile | 4 +- PluginContext.cpp | 97 +- PluginContext.h | 48 +- README | 37 +- RadiusClass/RadiusPacket.cpp | 8 +- RadiusClass/RadiusPacket.h | 1 + RadiusClass/main.cpp | 128 +-- ToDo | 10 +- User.h | 2 +- UserAcct.cpp | 134 +-- UserAcct.h | 2 +- UserAuth.cpp | 74 +- UserPlugin.cpp | 13 + UserPlugin.h | 4 + clean.sh | 5 +- main.cpp | 149 ++- openvpn-plugin.h | 342 ++++++- radiusplugin.cnf | 2 +- radiusplugin.cpp | 1878 ++++++++++++++++++---------------- radiusplugin.h | 11 + 24 files changed, 1849 insertions(+), 1199 deletions(-) diff --git a/AccountingProcess.cpp b/AccountingProcess.cpp index 618b4bc..e6093aa 100644 --- a/AccountingProcess.cpp +++ b/AccountingProcess.cpp @@ -50,12 +50,12 @@ void AccountingProcess::Accounting(PluginContext * context) } catch (Exception &e) { - cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT:" << e <<"\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT:" << e <<"\n"; goto done; } if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: Started, RESPONSE_INIT_SUCCEEDED was sent to Foreground Process.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: Started, RESPONSE_INIT_SUCCEEDED was sent to Foreground Process.\n"; // Event loop @@ -75,7 +75,7 @@ void AccountingProcess::Accounting(PluginContext * context) command = context->acctsocketforegr.recvInt(); if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: Get a command.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: Get a command.\n"; switch (command) { @@ -85,7 +85,7 @@ void AccountingProcess::Accounting(PluginContext * context) { if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: New User.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: New User.\n"; //allocate memory user= new UserAcct; @@ -103,7 +103,7 @@ void AccountingProcess::Accounting(PluginContext * context) user->setUntrustedPort(context->acctsocketforegr.recvStr()); context->acctsocketforegr.recvBuf(user); if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: New user acct: username: " << user->getUsername() << ", interval: " << user->getAcctInterimInterval() << ", calling station: " << user->getCallingStationId() << ", commonname: " << user->getCommonname() << ", framed ip: " << user->getFramedIp() <<".\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: New user acct: username: " << user->getUsername() << ", interval: " << user->getAcctInterimInterval() << ", calling station: " << user->getCallingStationId() << ", commonname: " << user->getCommonname() << ", framed ip: " << user->getFramedIp() <<".\n"; //set the starttime @@ -117,10 +117,10 @@ void AccountingProcess::Accounting(PluginContext * context) { if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: Start packet was send.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: Start packet was send.\n"; if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: User was added to accounting scheduler.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: User was added to accounting scheduler.\n"; //set the system routes user->addSystemRoutes(context); @@ -131,7 +131,7 @@ void AccountingProcess::Accounting(PluginContext * context) if(script.length() > 0) { if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: Call vendor specific attribute script.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: Call vendor specific attribute script.\n"; if(callVsaScript(context, user, 1, 0) != 0) { throw Exception("Vendor specific attribute script failed.\n"); @@ -157,19 +157,19 @@ void AccountingProcess::Accounting(PluginContext * context) } catch (Exception &e) { - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: "<< e << "!\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: "<< e << "!\n"; context->acctsocketforegr.send(RESPONSE_FAILED); //close the background process, if the ipc socket is bad if (e.getErrnum()==Exception::SOCKETSEND || e.getErrnum()==Exception::SOCKETRECV) { - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: Error in socket!\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: Error in socket!\n"; goto done; } } catch (...) { context->acctsocketforegr.send(RESPONSE_FAILED); - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: Unknown Exception!\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: Unknown Exception!\n"; } delete user; break; @@ -178,7 +178,7 @@ void AccountingProcess::Accounting(PluginContext * context) case DEL_USER: if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Delete user from accounting.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Delete user from accounting.\n"; //receive the information try @@ -187,7 +187,7 @@ void AccountingProcess::Accounting(PluginContext * context) } catch(Exception &e) { - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: "<< e << "!\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: "<< e << "!\n"; //close the background process, if the ipc socket is bad if (e.getErrnum()==Exception::SOCKETSEND || e.getErrnum()==Exception::SOCKETRECV) { @@ -196,7 +196,7 @@ void AccountingProcess::Accounting(PluginContext * context) } catch (...) { - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: Unknown Exception!\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: Unknown Exception!\n"; } //find the user, he must be already there @@ -205,7 +205,7 @@ void AccountingProcess::Accounting(PluginContext * context) if (user) { if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: Stop acct: username: " << user->getUsername()<< ", calling station: " << user->getCallingStationId()<< ", commonname: " << user->getCommonname() << ".\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: Stop acct: username: " << user->getUsername()<< ", calling station: " << user->getCallingStationId()<< ", commonname: " << user->getCommonname() << ".\n"; //delete the system routes user->delSystemRoutes(context); @@ -219,7 +219,7 @@ void AccountingProcess::Accounting(PluginContext * context) { //string command= context->conf.getVsaScript() + string(" ") + string("ACTION=CLIENT_CONNECT")+string(" ")+string("USERNAME=")+user->getUsername()+string(" ")+string("COMMONNAME=")+user->getCommonname()+string(" ")+string("UNTRUSTED_IP=")+user->getCallingStationId() + string(" ") + string("UNTRUSTED_PORT=") + user->getUntrustedPort() + user->getVsaString(); if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: Call vendor specific attribute script.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: Call vendor specific attribute script.\n"; if(callVsaScript(context, user, 1, 0) != 0) { throw Exception("Vendor specific attribute script failed.\n"); @@ -232,7 +232,7 @@ void AccountingProcess::Accounting(PluginContext * context) scheduler.delUser(context, user); if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: User with key: " << key << " was deleted from accouting.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: User with key: " << key << " was deleted from accouting.\n"; //send the parent process the ok context->acctsocketforegr.send(RESPONSE_SUCCEEDED); @@ -241,17 +241,17 @@ void AccountingProcess::Accounting(PluginContext * context) } catch(Exception &e) { - cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: " << e << "\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: " << e << "\n"; goto done; } catch (...) { - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: Unknown Exception!\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: Unknown Exception!\n"; } } else { - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: No user with this key "<< key <<".\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: No user with this key "<< key <<".\n"; context->acctsocketforegr.send(RESPONSE_FAILED); } @@ -260,15 +260,15 @@ void AccountingProcess::Accounting(PluginContext * context) //exit the loop case COMMAND_EXIT: if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Get command exit.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Get command exit.\n"; goto done; case -1: - cerr << "RADIUS-PLUGIN: BACKGROUND: read error on command channel.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND: read error on command channel.\n"; break; default: - cerr << "RADIUS-PLUGIN: BACKGROUND: unknown command code: code= "<< command <<", exiting.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND: unknown command code: code= "<< command <<", exiting.\n"; goto done; @@ -282,7 +282,7 @@ void AccountingProcess::Accounting(PluginContext * context) //end the process if(1) scheduler.delallUsers(context); - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: EXIT\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: EXIT\n"; return; } @@ -459,11 +459,11 @@ int AccountingProcess::callVsaScript(PluginContext * context, User * user, unsig /* FIFO bereits vorhanden - kein fataler Fehler */ if(errno == EEXIST) { - cerr << "RADIUS-PLUGIN:FIFO already exist."; + cerr << getTime() << "RADIUS-PLUGIN:FIFO already exist."; } else { - cerr <<"RADIUS-PLUGIN: Error in mkfifio()"; + cerr << getTime() <<"RADIUS-PLUGIN: Error in mkfifio()"; return -1; } } @@ -471,19 +471,19 @@ int AccountingProcess::callVsaScript(PluginContext * context, User * user, unsig if (fd_fifo == -1) { - cerr <<"RADIUS-PLUGIN: Error in opening pipe to VSAScript."; + cerr << getTime() <<"RADIUS-PLUGIN: Error in opening pipe to VSAScript."; return -1; } string exe=string(context->conf.getVsaScript()) + " " + string(context->conf.getVsaNamedPipe()); if (write (fd_fifo, buf, buflen) != buflen) { - cerr << "RADIUS-PLUGIN: Could not write in Pipe to VSAScript!"; + cerr << getTime() << "RADIUS-PLUGIN: Could not write in Pipe to VSAScript!"; return -1; } if(system(exe.c_str())!=0) { - cerr << "RADIUS-PLUGIN: Error in VSAScript!"; + cerr << getTime() << "RADIUS-PLUGIN: Error in VSAScript!"; return -1; } close(fd_fifo); diff --git a/AcctScheduler.cpp b/AcctScheduler.cpp index 0e6544e..6cd1bcc 100755 --- a/AcctScheduler.cpp +++ b/AcctScheduler.cpp @@ -84,18 +84,18 @@ void AcctScheduler::delUser(PluginContext * context, UserAcct *user) 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"; + cerr << getTime() << "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"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Stop packet was sent. CN: " << user->getCommonname() << ".\n"; } else { - cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Error on sending stop packet."; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Error on sending stop packet."; } if (user->getAcctInterimInterval()==0) @@ -120,7 +120,7 @@ void AcctScheduler::delallUsers(PluginContext * context) { map::iterator iter1, iter2; if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Delete all users."; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Delete all users."; iter1=activeuserlist.begin(); iter2=activeuserlist.end(); @@ -160,7 +160,7 @@ void AcctScheduler::doAccounting(PluginContext * context) if ( t>=iter1->second.getNextUpdate()) { if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Scheduler: Update for User " << iter1->second.getUsername() << ".\n"; + cerr << getTime() << "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); @@ -170,7 +170,7 @@ void AcctScheduler::doAccounting(PluginContext * context) iter1->second.sendUpdatePacket(context); if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND-ACCT: Scheduler: Update packet for User " << iter1->second.getUsername() << " was send.\n"; + cerr << getTime() << "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()); @@ -199,7 +199,7 @@ void AcctScheduler::parseStatusFile(PluginContext *context, uint64_t *bytesin, u if (file.is_open()) { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND ACCT: Scheduler: Read Statusfile.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND ACCT: Scheduler: Read Statusfile.\n"; //find the key, is delimited with a ',' from the informations @@ -224,14 +224,14 @@ void AcctScheduler::parseStatusFile(PluginContext *context, uint64_t *bytesin, u else { - cerr << "RADIUS-PLUGIN: BACKGROUND ACCT: No accounting data was found for "<< key <<".\n"; + cerr << getTime() << "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"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Statusfile "<< context->conf.getStatusFile() <<" could not opened.\n"; } } diff --git a/AuthenticationProcess.cpp b/AuthenticationProcess.cpp index 14a7fdf..c375cbe 100644 --- a/AuthenticationProcess.cpp +++ b/AuthenticationProcess.cpp @@ -50,11 +50,11 @@ void AuthenticationProcess::Authentication(PluginContext * context) } catch(Exception &e) { - cerr << "RADIUS-PLUGIN: BACKGROUND AUTH:" << e <<"\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH:" << e <<"\n"; goto done; } if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND AUTH: Started, RESPONSE_INIT_SUCCEEDED was sent to Foreground Process.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: Started, RESPONSE_INIT_SUCCEEDED was sent to Foreground Process.\n"; // Event loop while (1) { @@ -80,10 +80,10 @@ void AuthenticationProcess::Authentication(PluginContext * context) user->setFramedIp(context->authsocketforegr.recvStr()); if (DEBUG (context->getVerbosity()) && (user->getFramedIp().compare("") == 0)) - cerr << "RADIUS-PLUGIN: BACKGROUND AUTH: New user auth: username: " << user->getUsername() << ", password: *****, calling station: " << user->getCallingStationId() << ", commonname: " << user->getCommonname() << ".\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: New user auth: username: " << user->getUsername() << ", password: *****, calling station: " << user->getCallingStationId() << ", commonname: " << user->getCommonname() << ".\n"; if (DEBUG (context->getVerbosity()) && (user->getFramedIp().compare("") !=0 )) - cerr << "RADIUS-PLUGIN: BACKGROUND AUTH: Old user ReAuth: username: " << user->getUsername() << ", password: *****, calling station: " << user->getCallingStationId() << ", commonname: " << user->getCommonname() << ".\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: Old user ReAuth: username: " << user->getUsername() << ", password: *****, calling station: " << user->getCallingStationId() << ", commonname: " << user->getCommonname() << ".\n"; //send the AcceptRequestPacket if (user->sendAcceptRequestPacket(context)==0) /* Succeeded */ @@ -116,7 +116,7 @@ void AuthenticationProcess::Authentication(PluginContext * context) delete user; if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND AUTH: Auth succeeded in radius_server().\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: Auth succeeded in radius_server().\n"; @@ -129,7 +129,7 @@ void AuthenticationProcess::Authentication(PluginContext * context) } catch (Exception &e) { - cerr << e; + cerr << getTime() << e; delete user; if (e.getErrnum()==Exception::SOCKETSEND || e.getErrnum()==Exception::SOCKETRECV) { @@ -149,18 +149,18 @@ void AuthenticationProcess::Authentication(PluginContext * context) goto done; case -1: - cerr << "RADIUS-PLUGIN: BACKGROUND AUTH: read error on command channel.\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: read error on command channel.\n"; break; default: - cerr << "RADIUS-PLUGIN: BACKGROUND AUTH: unknown command code: code="<verb=0; this->sessionid=1; - + + this->stopthread=false; + this->startthread=true; } /** The destructor clears the users and nasportlist.*/ @@ -102,9 +104,9 @@ void PluginContext::delNasPort(int num) */ void PluginContext::addUser(UserPlugin * newuser) { - pair::iterator,bool> success; + pair::iterator,bool> success; - success=users.insert(make_pair(newuser->getKey(),*newuser)); + success=users.insert(make_pair(newuser->getKey(),newuser)); if(success.second==false) { @@ -131,10 +133,10 @@ void PluginContext::delUser(string key) */ UserPlugin * PluginContext::findUser(string key) { - map::iterator iter = users.find(key); + map::iterator iter = users.find(key); if (iter != users.end()) { - return &(iter->second); + return iter->second; } return NULL; } @@ -200,3 +202,88 @@ int PluginContext::getSessionId(void) { return this->sessionid; } + + +/**The method adds an new user to the user list of users waiting for authentication + * @param newuser A pointer to the user. + */ +void PluginContext::addNewUser(UserPlugin * newuser) +{ + this->newusers.push_back(newuser); +} + +/**The method return the first element in the list of waiting users. + */ +UserPlugin * PluginContext::getNewUser() +{ + + + UserPlugin * user = this->newusers.front(); + this->newusers.pop_front(); + return user; + +} + +pthread_cond_t * PluginContext::getCondSend(void ) +{ + return &condsend; +} +pthread_cond_t * PluginContext::getCondRecv(void ) +{ + return &condrecv; +} + +pthread_mutex_t * PluginContext::getMutexSend(void ) +{ + return &mutexsend; +} + +pthread_mutex_t * PluginContext::getMutexRecv(void ) +{ + return &mutexrecv; +} + + +pthread_t * PluginContext::getThread() +{ + return &thread; +} + +int PluginContext::getResult() +{ + return result; +} + +void PluginContext::setResult(int r) +{ + result=r; +} + +bool PluginContext::UserWaitingtoAuth() +{ + if (this->newusers.size()>0) return true; + else return false; +} + + +bool PluginContext::getStopThread() +{ + return stopthread; +} + +void PluginContext::setStopThread(bool s) +{ + stopthread=s; +} + + +bool PluginContext::getStartThread() +{ + return startthread; +} + +void PluginContext::setStartThread(bool value) +{ + startthread=value; +} + diff --git a/PluginContext.h b/PluginContext.h index 626665b..42abbab 100755 --- a/PluginContext.h +++ b/PluginContext.h @@ -32,6 +32,7 @@ #include #include #include +#include using std::map; @@ -52,13 +53,23 @@ class PluginContext int verb; /**< Verbosity level of OpenVPN. */ - map users; /**< The user list of the plugin in for the foreground process.*/ - - - list nasportlist; /**< The port list. Every user gets an unipue port on connect. The number is deleted if the user disconnects, a new user can + map users; /**< The user list of the plugin in for the foreground process which are authenticated.*/ + list< UserPlugin *> newusers; /**< The user list of the plugin in for the foreground process which are waiting for authentication.*/ + + list nasportlist; /**< The port list. Every user gets an unipue port on connect. The number is deleted if the user disconnects, a new user can get the number again. This is important for dynamic IP address assignment via the radius server.*/ - int sessionid; /**< Every user gets a new session id. The session is never decremented.*/ + int sessionid; /**< Every user gets a new session id. The session is never decremented.*/ + + pthread_cond_t condsend; + pthread_mutex_t mutexsend; + pthread_cond_t condrecv; + pthread_mutex_t mutexrecv; + pthread_t thread; + bool stopthread; + bool startthread; + int result; + public: @@ -93,7 +104,32 @@ class PluginContext int getSessionId(void); - + pthread_cond_t * getCondSend(void); + //void setCond(pthread_cond_t); + pthread_cond_t * getCondRecv(void); + + pthread_mutex_t * getMutexSend(void); + pthread_mutex_t * getMutexRecv(void); + //void setMutex(pthread_mutex_t); + + UserPlugin * getNewUser(); + void addNewUser(UserPlugin * newuser); + + pthread_t * getThread(); + + int getResult(); + void setResult(int); + + bool getStopThread(); + void setStopThread(bool); + + bool UserWaitingtoAuth(); + + bool getStartThread(); + void setStartThread(bool); + + + }; diff --git a/README b/README index 492b4cb..cd5edd8 100755 --- a/README +++ b/README @@ -59,9 +59,10 @@ INSTALL: The configuration is casesensetive, for an example see radiusplugin.cnf. 5. Set some configuration in the config file of the OpenVPN server: - status /var/log/openvpn/status.log 1 # The status, where the plugin reads the accounting information from. -6. Set some configuration in the config file of the OpenVPN client: +6. Configure in the config file of the OpenVPN client: - auth-user-pass [/etc/openvpn/passwd] # Set this for sending a username and password to the server, this values are the username and password for the radius authentication. -7. Maybe write your own script for vendor specific attributes (see section VENDOR SPECIFIC ATTRIBUTES). +7. If you use auth_control_file (>= OpenVPN 2.1 rc8), the plugin directory needs write permission to the OpenVPN directory. +8. Maybe write your own script for vendor specific attributes (see section VENDOR SPECIFIC ATTRIBUTES). OTHER DOCUMENTATION @@ -72,17 +73,19 @@ http://www.roessner-net.com/ FREERADIUS EXAMPLE ------------------- -user1 Auth-Type := Local, User-Password == "testing" - Service-Type = Framed-User, - Framed-IP-Netmask = 255.255.255.0, - Framed-Routing = Broadcast-Listen, - Framed-Compression = Van-Jacobsen-TCP-IP, - Framed-Route += "192.168.101.0/26 10.8.0.1/32 1", - Framed-Route += "192.168.111.0/24 10.8.0.1/32 1", - Framed-Route += "192.168.112.0/24 10.8.0.1/32 1", - Acct-Interim-Interval=5, - Framed-Protocol = PPP, - Framed-IP-Address = 10.8.0.100 +user1 Cleartext-Password := "testing" + Service-Type = Framed-User, + Framed-IP-Netmask = 255.255.255.0, + Framed-IP-Address = 10.8.0.33, + Framed-Routing = Broadcast-Listen, + Framed-Compression = Van-Jacobsen-TCP-IP, + Framed-Route += "192.168.101.0/26 10.8.0.1/32 1", + Framed-Route += "192.168.111.0/24 10.8.0.1/32 1", + Framed-Route += "192.168.112.0/24 10.8.0.1/32 1", + Acct-Interim-Interval=5, + Ascend-Data-Rate=100, + Ascend-Xmit-Rate=200, + Framed-Protocol = PPP The Framed-Route attribute must in the format as shown above! @@ -92,7 +95,7 @@ COMPILE (tested with Debian on x86, for other architectures see section TROUBLESHOOTING): >$ make or ->$ g++ -Wall -shared -o radiusplugin.so AccountingProcess.cpp Exception.cpp PluginContext.cpp UserAuth.cpp AcctScheduler.cpp IpcSocket.cpp radiusplugin.cpp User.cpp AuthenticationProcess.cpp main.cpp UserAcct.cpp UserPlugin.cpp Config.cpp RadiusClass/RadiusAttribute.cpp RadiusClass/RadiusPacket.cpp RadiusClass/RadiusConfig.cpp RadiusClass/RadiusServer.cpp RadiusClass/RadiusVendorSpecificAttribute.cpp -lgcrypt +>$ g++ -Wall -shared -fpic -o radiusplugin.so AccountingProcess.cpp Exception.cpp PluginContext.cpp UserAuth.cpp AcctScheduler.cpp IpcSocket.cpp radiusplugin.cpp User.cpp AuthenticationProcess.cpp main.cpp UserAcct.cpp UserPlugin.cpp Config.cpp RadiusClass/RadiusAttribute.cpp RadiusClass/RadiusPacket.cpp RadiusClass/RadiusConfig.cpp RadiusClass/RadiusServer.cpp RadiusClass/RadiusVendorSpecificAttribute.cpp -lgcrypt -lpthread RADIUS PACKETS and OpenVPN events (see http://openvpn.net/man.html SCRIPTING AND ENVIRONMENTAL VARIABLES) @@ -118,8 +121,8 @@ RADIUS ATTRIBUTES WHICH PARSED BY THE PLUGIN AND WRITE TO THE CLIENT CONFIG FILE VENDOR SPECIFIC ATTRIBUTES --------------------------- -If you want use vendor specific attributes the plugin can call your own program or script at OpenVPN action -CLIENT-CONNECT and CLIENT-DISCONNECT (next version also AUTH_USER_PASS_VERIFY). +If you want use vendor specific attributes the plugin can call your own program or script at the OpenVPN action +CLIENT-CONNECT and CLIENT-DISCONNECT. If you want to use the feature you have specify the program and a named pipe for communication in the config file. The file vsascript.pl shows an example. @@ -194,6 +197,8 @@ TROUBLESHOOTING - Error at compiling: DBG: md_enable: algorithm -4195948 not available: - Make sure that you use libgrypt 1.2.0 or higher. +- The plugin can't write the auth_control_file. + - The plugin needs write permission in the OpenVPN directory. diff --git a/RadiusClass/RadiusPacket.cpp b/RadiusClass/RadiusPacket.cpp index 7ba526d..c409ce8 100755 --- a/RadiusClass/RadiusPacket.cpp +++ b/RadiusClass/RadiusPacket.cpp @@ -137,7 +137,7 @@ int RadiusPacket::addRadiusAttribute(RadiusAttribute *ra) { if (ra->getLength()<1) { - fprintf(stderr,"No value in the Attribute!"); + cerr << "No value in the Attribute!\n"; return NO_VALUE_IN_ATTRIBUTE; } @@ -327,7 +327,7 @@ int RadiusPacket::unShapeRadiusPacket(void) // RADIUS packet header decoding this->code=this->recvbuffer[0]; - //fprintf(stderr, "\n\nCODE: %s\n\n", this->code); + //cerr << getTime() << "\n\nCODE: %s\n\n", this->code); this->identifier=this->recvbuffer[1]; memcpy(this->authenticator,recvbuffer+4,RADIUS_PACKET_AUTHENTICATOR_LEN); @@ -431,7 +431,7 @@ int RadiusPacket::radiusSend(list::iterator server) // Socket creation if((socket2Radius = socket(AF_INET, SOCK_DGRAM, 0))<0) { - fprintf(stderr,"cannot open socket: %s\n",strerror(errno)); + cerr << "Cannot open socket: "<< strerror(errno) <<"\n"; return SOCKET_ERROR; } @@ -443,7 +443,7 @@ int RadiusPacket::radiusSend(list::iterator server) //Bind the socket port, if(bind(socket2Radius,(struct sockaddr*)&cliAddr,sizeof(struct sockaddr))<0) { - fprintf(stderr,"cannot bind port: %s\n",strerror(errno)); + cerr << "Cannot bind port: " << strerror(errno) << "\n"; socket2Radius=-1; return BIND_ERROR; } diff --git a/RadiusClass/RadiusPacket.h b/RadiusClass/RadiusPacket.h index f7d7f6e..7b02408 100755 --- a/RadiusClass/RadiusPacket.h +++ b/RadiusClass/RadiusPacket.h @@ -43,6 +43,7 @@ #include "RadiusAttribute.h" #include "RadiusServer.h" + #include #include #include diff --git a/RadiusClass/main.cpp b/RadiusClass/main.cpp index c70175d..354c8be 100644 --- a/RadiusClass/main.cpp +++ b/RadiusClass/main.cpp @@ -194,19 +194,19 @@ int main_test (void) ra2.setValue(string("testing")); if(packet_access.addRadiusAttribute(&ra1)) { - fprintf(stderr, "RADIUS-CLASS: Fail to add attribute ATTRIB_User_Name.\n"); + cerr << getTime() << "RADIUS-CLASS: Fail to add attribute ATTRIB_User_Name.\n"; } if (packet_access.addRadiusAttribute(&ra2)) { - fprintf(stderr, "RADIUS-CLASS: Fail to add attribute ATTRIB_User_Password.\n"); + cerr << getTime() << "RADIUS-CLASS: Fail to add attribute ATTRIB_User_Password.\n"; } if (packet_access.addRadiusAttribute(&ra3)) { - fprintf(stderr, "RADIUS-CLASS: Fail to add attribute ATTRIB_NAS_Port.\n"); + cerr << getTime() << "RADIUS-CLASS: Fail to add attribute ATTRIB_NAS_Port.\n"; } if (packet_access.addRadiusAttribute(&ra4)) { - fprintf(stderr, "RADIUS-CLASS: Fail to add attribute ATTRIB_Calling_Station_Id.\n"); + cerr << getTime() << "RADIUS-CLASS: Fail to add attribute ATTRIB_Calling_Station_Id.\n"; } //get information from the config and add it to the packet if(strcmp(config.getNASIdentifier(),"")) @@ -214,7 +214,7 @@ int main_test (void) ra5.setValue(config.getNASIdentifier()); if (packet_access.addRadiusAttribute(&ra5)) { - fprintf(stderr, "RADIUS-CLASS: Fail to add attribute ATTRIB_NAS_Identifier.\n"); + cerr << getTime() << "RADIUS-CLASS: Fail to add attribute ATTRIB_NAS_Identifier.\n"; } } @@ -222,12 +222,12 @@ int main_test (void) { if(ra6.setValue(config.getNASIpAddress())!=0) { - fprintf(stderr, "RADIUS-CLASS: Fail to set value ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-CLASS: Fail to set value ATTRIB_NAS_Ip_Address.\n"; } else if (packet_access.addRadiusAttribute(&ra6)) { - fprintf(stderr, "RADIUS-CLASS: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-CLASS: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"; } } if(strcmp(config.getNASPortType(),"")) @@ -235,7 +235,7 @@ int main_test (void) ra7.setValue(config.getNASPortType()); if (packet_access.addRadiusAttribute(&ra7)) { - fprintf(stderr, "RADIUS-CLASS: Fail to add attribute ATTRIB_NAS_Port_Type.\n"); + cerr << getTime() << "RADIUS-CLASS: Fail to add attribute ATTRIB_NAS_Port_Type.\n"; } } @@ -244,7 +244,7 @@ int main_test (void) ra8.setValue(config.getServiceType()); if (packet_access.addRadiusAttribute(&ra8)) { - fprintf(stderr, "RADIUS-CLASS: Fail to add attribute ATTRIB_Service_Type.\n"); + cerr << getTime() << "RADIUS-CLASS: Fail to add attribute ATTRIB_Service_Type.\n"; } } @@ -288,7 +288,7 @@ int main_test (void) //send the packet to the first server from the list if (packet_access.radiusSend(server)<0) { - fprintf(stderr, "RADIUS-CLASS: Packet was not send.\n"); + cerr << getTime() << "RADIUS-CLASS: Packet was not send.\n"; } //receive the packet, if the server doesn't response send the packet to the next server in list. @@ -306,13 +306,13 @@ int main_test (void) //If the radius server denied the access or sends a ACCESS_CHALLANGE-packet. else { - fprintf (stderr, "RADIUS-CLASS: Get ACCESS_REJECT or ACCESS_CHALLANGE-Packet.->ACCESS-DENIED.\n"); + cerr << getTime() << "RADIUS-CLASS: Get ACCESS_REJECT or ACCESS_CHALLANGE-Packet.->ACCESS-DENIED.\n"; } } else { - fprintf (stderr, "RADIUS-CLASS: Got no or bad response from radius server.\n"); + cerr << getTime() << "RADIUS-CLASS: Got no or bad response from radius server.\n"; } @@ -327,31 +327,31 @@ int main_test (void) //add the attributes to the packet if(packet_accounting_start.addRadiusAttribute(&ra1)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"; } if (packet_accounting_start.addRadiusAttribute(&ra3)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"; } if (packet_accounting_start.addRadiusAttribute(&ra4)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"; } if (packet_accounting_start.addRadiusAttribute(&ra10)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Session_Id.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Session_Id.\n"; } //set status type: start = 1 (see RADIUS RFC) ra11.setValue(string("1")); if (packet_accounting_start.addRadiusAttribute(&ra11)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Status_Type.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Status_Type.\n"; } @@ -361,7 +361,7 @@ int main_test (void) ra5.setValue(config.getNASIdentifier()); if (packet_accounting_start.addRadiusAttribute(&ra5)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"; } } @@ -369,12 +369,12 @@ int main_test (void) { if(ra6.setValue(config.getNASIpAddress())!=0) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"; } if (packet_accounting_start.addRadiusAttribute(&ra6)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"; } } if(strcmp(config.getNASPortType(),"")) @@ -382,7 +382,7 @@ int main_test (void) ra7.setValue(config.getNASPortType()); if (packet_accounting_start.addRadiusAttribute(&ra7)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"; } } @@ -391,7 +391,7 @@ int main_test (void) ra8.setValue(config.getServiceType()); if (packet_accounting_start.addRadiusAttribute(&ra8)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"; } } if(strcmp(config.getFramedProtocol(),"")) @@ -399,13 +399,13 @@ int main_test (void) ra12.setValue(config.getFramedProtocol()); if (packet_accounting_start.addRadiusAttribute(&ra12)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_FramedProtocol.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_FramedProtocol.\n"; } } ra9.setValue(string("111.222.111.111")); if (packet_accounting_start.addRadiusAttribute(&ra9)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"; } @@ -413,7 +413,7 @@ int main_test (void) //send the packet_accounting_start if (packet_accounting_start.radiusSend(server)<0) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Packet was not send.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Packet was not send.\n"; } //receive the response @@ -422,13 +422,13 @@ int main_test (void) //is is a accounting resopnse ? if(packet_accounting_start.getCode()==ACCOUNTING_RESPONSE) { - fprintf (stdout, "RADIUS-CLASS: Get ACCOUNTING_RESPONSET-Packet.\n"); + cerr << getTime() << "RADIUS-CLASS: Get ACCOUNTING_RESPONSET-Packet.\n"; } } else { - fprintf (stderr, "RADIUS-CLASS: Got no or bad response from radius server.\n"); + cerr << getTime() << "RADIUS-CLASS: Got no or bad response from radius server.\n"; } // Send a ACCOUNTING-REQUEST-PACKET, Status-Type:Update @@ -441,17 +441,17 @@ int main_test (void) //add the attributes to the packet if(packet_accounting_update.addRadiusAttribute(&ra1)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"; } if (packet_accounting_update.addRadiusAttribute(&ra3)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"; } if (packet_accounting_update.addRadiusAttribute(&ra4)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"; } @@ -459,29 +459,29 @@ int main_test (void) if (packet_accounting_update.addRadiusAttribute(&ra10)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Session_Id.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Session_Id.\n"; } //set status type: update = 3(see RADIUS RFC) ra11.setValue(string("3")); if (packet_accounting_update.addRadiusAttribute(&ra11)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Status_Type.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Status_Type.\n"; } if (packet_accounting_update.addRadiusAttribute(&ra13)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Octets.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Octets.\n"; } if (packet_accounting_update.addRadiusAttribute(&ra14)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Octets.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Octets.\n"; } if (packet_accounting_update.addRadiusAttribute(&ra14)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_Time.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_Time.\n"; } //get information from the config and add the attributes to the packet @@ -490,7 +490,7 @@ int main_test (void) ra5.setValue(config.getNASIdentifier()); if (packet_accounting_update.addRadiusAttribute(&ra5)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"; } } @@ -498,12 +498,12 @@ int main_test (void) { if(ra6.setValue(config.getNASIpAddress())!=0) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"; } if (packet_accounting_update.addRadiusAttribute(&ra6)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"; } } if(strcmp(config.getNASPortType(),"")) @@ -511,7 +511,7 @@ int main_test (void) ra7.setValue(config.getNASPortType()); if (packet_accounting_update.addRadiusAttribute(&ra7)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"; } } @@ -520,7 +520,7 @@ int main_test (void) ra8.setValue(config.getServiceType()); if (packet_accounting_update.addRadiusAttribute(&ra8)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"; } } if(strcmp(config.getFramedProtocol(),"")) @@ -528,13 +528,13 @@ int main_test (void) ra12.setValue(config.getFramedProtocol()); if (packet_accounting_update.addRadiusAttribute(&ra12)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_FramedProtocol.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_FramedProtocol.\n"; } } ra9.setValue(string("111.222.111.111")); if (packet_accounting_update.addRadiusAttribute(&ra9)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"; } @@ -542,7 +542,7 @@ int main_test (void) //send the packet_accounting_update if (packet_accounting_update.radiusSend(server)<0) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Packet was not send.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Packet was not send.\n"; } //receive the response @@ -551,7 +551,7 @@ int main_test (void) //is is a accounting resopnse ? if(packet_accounting_update.getCode()==ACCOUNTING_RESPONSE) { - fprintf (stdout, "RADIUS-CLASS: BACKGROUND-ACCT: Get ACCOUNTING_RESPONSET-Packet.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Get ACCOUNTING_RESPONSET-Packet.\n"; } @@ -559,7 +559,7 @@ int main_test (void) } else { - fprintf (stderr, "RADIUS-CLASS: Got no or bad response from radius server.\n"); + cerr << getTime() << "RADIUS-CLASS: Got no or bad response from radius server.\n"; } // Send a ACCOUNTING-REQUEST-PACKET, Status-Type:Stop @@ -572,17 +572,17 @@ int main_test (void) //add the attributes to the packet if(packet_accounting_stop.addRadiusAttribute(&ra1)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"; } if (packet_accounting_stop.addRadiusAttribute(&ra3)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"; } if (packet_accounting_stop.addRadiusAttribute(&ra4)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"; } @@ -590,29 +590,29 @@ int main_test (void) if (packet_accounting_stop.addRadiusAttribute(&ra10)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Session_Id.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Session_Id.\n"; } //set status type: update = 2(see RADIUS RFC) ra11.setValue(string("2")); if (packet_accounting_stop.addRadiusAttribute(&ra11)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Status_Type.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Status_Type.\n"; } if (packet_accounting_stop.addRadiusAttribute(&ra13)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Octets.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Octets.\n"; } if (packet_accounting_stop.addRadiusAttribute(&ra14)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Octets.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Octets.\n"; } if (packet_accounting_stop.addRadiusAttribute(&ra14)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_Time.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_Time.\n"; } //get information from the config and add the attributes to the packet @@ -621,7 +621,7 @@ int main_test (void) ra5.setValue(config.getNASIdentifier()); if (packet_accounting_stop.addRadiusAttribute(&ra5)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"; } } @@ -629,12 +629,12 @@ int main_test (void) { if(ra6.setValue(config.getNASIpAddress())!=0) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"; } if (packet_accounting_stop.addRadiusAttribute(&ra6)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"; } } if(strcmp(config.getNASPortType(),"")) @@ -642,7 +642,7 @@ int main_test (void) ra7.setValue(config.getNASPortType()); if (packet_accounting_stop.addRadiusAttribute(&ra7)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"; } } @@ -651,7 +651,7 @@ int main_test (void) ra8.setValue(config.getServiceType()); if (packet_accounting_stop.addRadiusAttribute(&ra8)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"; } } if(strcmp(config.getFramedProtocol(),"")) @@ -659,13 +659,13 @@ int main_test (void) ra12.setValue(config.getFramedProtocol()); if (packet_accounting_stop.addRadiusAttribute(&ra12)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_FramedProtocol.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_FramedProtocol.\n"; } } ra9.setValue(string("111.222.111.111")); if (packet_accounting_stop.addRadiusAttribute(&ra9)) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"; } @@ -673,7 +673,7 @@ int main_test (void) //send the packet_accounting_stop if (packet_accounting_stop.radiusSend(server)<0) { - fprintf(stderr, "RADIUS-CLASS: BACKGROUND-ACCT: Packet was not send.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Packet was not send.\n"; } //receive the response @@ -682,13 +682,13 @@ int main_test (void) //is is a accounting resopnse ? if(packet_accounting_stop.getCode()==ACCOUNTING_RESPONSE) { - fprintf (stdout, "RADIUS-CLASS: BACKGROUND-ACCT: Get ACCOUNTING_RESPONSET-Packet.\n"); + cerr << getTime() << "RADIUS-CLASS: BACKGROUND-ACCT: Get ACCOUNTING_RESPONSET-Packet.\n"; } } else { - fprintf (stderr, "RADIUS-CLASS: Got no or bad response from radius server.\n"); + cerr << getTime() << "RADIUS-CLASS: Got no or bad response from radius server.\n"; } cout << "\n---- End ----"; @@ -741,7 +741,7 @@ void parseResponsePacket(RadiusPacket *packet) } else { - fprintf(stderr,"RADIUS-CLASS: No attributes Acct Interim Interval or bad length.\n"); + cerr << getTime() <<"RADIUS-CLASS: No attributes Acct Interim Interval or bad length.\n"; } cout << "\nAcct-Interim-Interval: " << acct_interval; diff --git a/ToDo b/ToDo index a918444..947d0cc 100644 --- a/ToDo +++ b/ToDo @@ -1,10 +1,3 @@ -TODO (next version): ---------------------- -- OpenBSD compatible -- send commonname to RADIUS server -- vsascript call also at authentication -- support for vendor specific OpenVPN attributes - TODO (general): ---------------- - integrate system dependent code for system call route ... @@ -23,3 +16,6 @@ TODO (general): - get to know if no certificates are used - check if preconditions are ok - different status file version +- OpenBSD compatible +- send commonname to RADIUS server +- vsascript call also at authentication \ No newline at end of file diff --git a/User.h b/User.h index 5c99a39..c20eca7 100644 --- a/User.h +++ b/User.h @@ -25,7 +25,7 @@ #include #include #include -#include "openvpn-plugin.h" +//#include "openvpn-plugin.h" /** The datatype for sending and receiving data to and from the network */ diff --git a/UserAcct.cpp b/UserAcct.cpp index 8fb4961..acbc268 100755 --- a/UserAcct.cpp +++ b/UserAcct.cpp @@ -96,22 +96,22 @@ int UserAcct::sendUpdatePacket(PluginContext *context) //add the attributes to the radius packet if(packet.addRadiusAttribute(&ra1)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"; } if (packet.addRadiusAttribute(&ra2)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Password.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Password.\n"; } if (packet.addRadiusAttribute(&ra3)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"; } if (packet.addRadiusAttribute(&ra4)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"; } //get the values from the config and add them to the packet @@ -120,7 +120,7 @@ int UserAcct::sendUpdatePacket(PluginContext *context) ra5.setValue(context->radiusconf.getNASIdentifier()); if (packet.addRadiusAttribute(&ra5)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"; } } @@ -128,11 +128,11 @@ int UserAcct::sendUpdatePacket(PluginContext *context) { if(ra6.setValue(context->radiusconf.getNASIpAddress())!=0) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"; } if (packet.addRadiusAttribute(&ra6)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"; } } @@ -141,7 +141,7 @@ int UserAcct::sendUpdatePacket(PluginContext *context) ra7.setValue(context->radiusconf.getNASPortType()); if (packet.addRadiusAttribute(&ra7)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"; } } @@ -150,18 +150,18 @@ int UserAcct::sendUpdatePacket(PluginContext *context) ra8.setValue(context->radiusconf.getServiceType()); if (packet.addRadiusAttribute(&ra8)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"; } } if (packet.addRadiusAttribute(&ra9)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"; } if (packet.addRadiusAttribute(&ra10)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"; } if(strcmp(context->radiusconf.getFramedProtocol(),"")) @@ -169,37 +169,37 @@ int UserAcct::sendUpdatePacket(PluginContext *context) ra11.setValue(context->radiusconf.getFramedProtocol()); if (packet.addRadiusAttribute(&ra11)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Framed_Protocol.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Framed_Protocol.\n"; } } if (packet.addRadiusAttribute(&ra12)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Packets.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Packets.\n"; } if (packet.addRadiusAttribute(&ra13)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Packets.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Packets.\n"; } //calculate the session time ra14.setValue((time(NULL)-this->starttime)); if (packet.addRadiusAttribute(&ra14)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_Time.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_Time.\n"; } if (packet.addRadiusAttribute(&ra15)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Gigawords.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Gigawords.\n"; } if (packet.addRadiusAttribute(&ra16)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Gigawords.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Gigawords.\n"; } //send the packet to the server if (packet.radiusSend(server)<0) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Packet was not send.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Packet was not send.\n"; } //get the response @@ -209,7 +209,7 @@ int UserAcct::sendUpdatePacket(PluginContext *context) if(packet.getCode()==ACCOUNTING_RESPONSE) { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Get ACCOUNTING_RESPONSET-Packet.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Get ACCOUNTING_RESPONSET-Packet.\n"; return 0; @@ -218,7 +218,7 @@ int UserAcct::sendUpdatePacket(PluginContext *context) else { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: No response on accounting request.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: No response on accounting request.\n"; return 1; } @@ -270,20 +270,20 @@ int UserAcct::sendStartPacket(PluginContext * context) //add the attributes to the packet if(packet.addRadiusAttribute(&ra1)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"; } if (packet.addRadiusAttribute(&ra2)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Password.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Password.\n"; } if (packet.addRadiusAttribute(&ra3)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"; } if (packet.addRadiusAttribute(&ra4)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"; } //get information from the config and add the attributes to the packet @@ -292,7 +292,7 @@ int UserAcct::sendStartPacket(PluginContext * context) ra5.setValue(context->radiusconf.getNASIdentifier()); if (packet.addRadiusAttribute(&ra5)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"; } } @@ -300,12 +300,12 @@ int UserAcct::sendStartPacket(PluginContext * context) { if(ra6.setValue(context->radiusconf.getNASIpAddress())!=0) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"; } if (packet.addRadiusAttribute(&ra6)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"; } } if(strcmp(context->radiusconf.getNASPortType(),"")) @@ -313,7 +313,7 @@ int UserAcct::sendStartPacket(PluginContext * context) ra7.setValue(context->radiusconf.getNASPortType()); if (packet.addRadiusAttribute(&ra7)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"; } } @@ -322,16 +322,16 @@ int UserAcct::sendStartPacket(PluginContext * context) ra8.setValue(context->radiusconf.getServiceType()); if (packet.addRadiusAttribute(&ra8)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"; } } if (packet.addRadiusAttribute(&ra9)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"; } if (packet.addRadiusAttribute(&ra10)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"; } if(strcmp(context->radiusconf.getFramedProtocol(),"")) @@ -339,14 +339,14 @@ int UserAcct::sendStartPacket(PluginContext * context) ra11.setValue(context->radiusconf.getFramedProtocol()); if (packet.addRadiusAttribute(&ra11)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Framed_Protocol.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Framed_Protocol.\n"; } } //send the packet if (packet.radiusSend(server)<0) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Packet was not send.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Packet was not send.\n"; } //receive the response @@ -356,7 +356,7 @@ int UserAcct::sendStartPacket(PluginContext * context) if(packet.getCode()==ACCOUNTING_RESPONSE) { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Get ACCOUNTING_RESPONSET-Packet.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Get ACCOUNTING_RESPONSET-Packet.\n"; return 0; @@ -364,7 +364,7 @@ int UserAcct::sendStartPacket(PluginContext * context) else { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: No response on accounting request.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: No response on accounting request.\n"; return 1; } @@ -427,20 +427,20 @@ int UserAcct::sendStopPacket(PluginContext * context) //add the attributes to the packet if(packet.addRadiusAttribute(&ra1)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_User_Name.\n"; } if (packet.addRadiusAttribute(&ra2)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_FramedIP_Adress.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_FramedIP_Adress.\n"; } if (packet.addRadiusAttribute(&ra3)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port.\n"; } if (packet.addRadiusAttribute(&ra4)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Calling_Station_Id.\n"; } //get information from th config and ad it to the packet @@ -449,7 +449,7 @@ int UserAcct::sendStopPacket(PluginContext * context) ra5.setValue(context->radiusconf.getNASIdentifier()); if (packet.addRadiusAttribute(&ra5)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Identifier.\n"; } } @@ -457,12 +457,12 @@ int UserAcct::sendStopPacket(PluginContext * context) { if(ra6.setValue(context->radiusconf.getNASIpAddress())!=0) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to set value ATTRIB_NAS_Ip_Address.\n"; } else if (packet.addRadiusAttribute(&ra6)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"; } } if(strcmp(context->radiusconf.getNASPortType(),"")) @@ -470,7 +470,7 @@ int UserAcct::sendStopPacket(PluginContext * context) ra7.setValue(context->radiusconf.getNASPortType()); if (packet.addRadiusAttribute(&ra7)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_NAS_Port_Type.\n"; } } @@ -479,16 +479,16 @@ int UserAcct::sendStopPacket(PluginContext * context) ra8.setValue(context->radiusconf.getServiceType()); if (packet.addRadiusAttribute(&ra8)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Service_Type.\n"; } } if (packet.addRadiusAttribute(&ra9)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"; } if (packet.addRadiusAttribute(&ra10)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_ID.\n"; } if(strcmp(context->radiusconf.getFramedProtocol(),"")) @@ -496,7 +496,7 @@ int UserAcct::sendStopPacket(PluginContext * context) ra11.setValue(context->radiusconf.getFramedProtocol()); if (packet.addRadiusAttribute(&ra11)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Framed_Protocol.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Framed_Protocol.\n"; } } @@ -504,31 +504,31 @@ int UserAcct::sendStopPacket(PluginContext * context) if (packet.addRadiusAttribute(&ra12)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Packets.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Packets.\n"; } if (packet.addRadiusAttribute(&ra13)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Packets.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Packets.\n"; } //calculate the session time ra14.setValue(time(NULL)-this->starttime); if (packet.addRadiusAttribute(&ra14)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_Time.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Session_Time.\n"; } if (packet.addRadiusAttribute(&ra15)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Gigawords.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Input_Gigawords.\n"; } if (packet.addRadiusAttribute(&ra16)) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Gigawords.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Fail to add attribute ATTRIB_Acct_Output_Gigawords.\n"; } //send the packet if (packet.radiusSend(server)<0) { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Packet was not send.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Packet was not send.\n"; } //get the response @@ -538,7 +538,7 @@ int UserAcct::sendStopPacket(PluginContext * context) if(packet.getCode()==ACCOUNTING_RESPONSE) { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Get ACCOUNTING_RESPONSE-Packet.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Get ACCOUNTING_RESPONSE-Packet.\n"; return 0; @@ -546,7 +546,7 @@ int UserAcct::sendStopPacket(PluginContext * context) else { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: No response on accounting request.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: No response on accounting request.\n"; return 1; } } @@ -585,7 +585,7 @@ void UserAcct::delSystemRoutes(PluginContext * context) len=strlen(route); if (len > 50) //this is to big!! but the length is variable { - fprintf(stderr,"RADIUS-PLUGIN: BACKGROUND-ACCT: Argument for Framed Route is to long (>100 Characters).\n"); + cerr << getTime() <<"RADIUS-PLUGIN: BACKGROUND-ACCT: Argument for Framed Route is to long (>100 Characters).\n"; } else { @@ -676,18 +676,18 @@ void UserAcct::delSystemRoutes(PluginContext * context) if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Create route string %s.\n",routestring); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Create route string "<< routestring <<".\n"; //system call if(system(routestring)!=0) //if(1)//-> the debugg can't context system() { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Route %s could not set. Route already set or bad route string.\n",routestring); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Route " << routestring << " could not set. Route already set or bad route string.\n"; } else { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Add route to system routing table.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Add route to system routing table.\n"; } //get the next route @@ -699,7 +699,7 @@ void UserAcct::delSystemRoutes(PluginContext * context) else { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: No routes for user in AccessAcceptPacket.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: No routes for user in AccessAcceptPacket.\n"; } //free the char array delete [] framedroutes; @@ -738,7 +738,7 @@ void UserAcct::addSystemRoutes(PluginContext * context) len=strlen(route); if (len > 50) //this is to big!! but the length is variable { - fprintf(stderr,"RADIUS-PLUGIN: BACKGROUND-ACCT: Argument for Framed Route is to long (>100 Characters).\n"); + cerr << getTime() <<"RADIUS-PLUGIN: BACKGROUND-ACCT: Argument for Framed Route is to long (>50 Characters).\n"; } else { @@ -764,7 +764,7 @@ void UserAcct::addSystemRoutes(PluginContext * context) } k=0; j++; - //get the framednetmask and add it to framednetmack_cidr + //get the framednetmask and add it to framednetmask_cidr while(route[j]!=' ' && j<=len) { framednetmask_cidr[k]=route[j]; @@ -830,18 +830,18 @@ void UserAcct::addSystemRoutes(PluginContext * context) if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Create route string %s.\n",routestring); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Create route string "<< routestring << ".\n"; //system call route if(system(routestring)!=0) //if(1)//-> the debugg can't context system() { - fprintf(stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Route %s could not set. Route already set or bad route string.\n",routestring); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Route " << routestring << " could not set. Route already set or bad route string.\n"; } else { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: Add route to system routing table.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: Add route to system routing table.\n"; } //get the next route @@ -852,7 +852,7 @@ void UserAcct::addSystemRoutes(PluginContext * context) else { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND-ACCT: No routes for user.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND-ACCT: No routes for user.\n"; } //fre the chat array delete [] framedroutes; @@ -1001,7 +1001,7 @@ int UserAcct::deleteCcdFile(PluginContext * context) } else { - cerr << "RADIUS-PLUGIN: Client config file was not deleted, overwriteccfiles is false \n."; + cerr << getTime() << "RADIUS-PLUGIN: Client config file was not deleted, overwriteccfiles is false \n."; } return 0; } diff --git a/UserAcct.h b/UserAcct.h index 13ef595..718b4ac 100755 --- a/UserAcct.h +++ b/UserAcct.h @@ -24,7 +24,7 @@ #include #include #include "RadiusClass/RadiusPacket.h" -#include "openvpn-plugin.h" +//#include "openvpn-plugin.h" #include "User.h" #include "UserPlugin.h" #include "PluginContext.h" diff --git a/UserAuth.cpp b/UserAuth.cpp index a9a5001..d968ae5 100755 --- a/UserAuth.cpp +++ b/UserAuth.cpp @@ -61,7 +61,7 @@ int UserAuth::sendAcceptRequestPacket(PluginContext * context) if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: radius_server().\n"); + cerr << getTime() << "RADIUS-PLUGIN: radius_server().\n"; //get the server list serverlist=context->radiusconf.getRadiusServer(); @@ -70,26 +70,26 @@ int UserAuth::sendAcceptRequestPacket(PluginContext * context) if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: Build password packet: password: *****, sharedSecret: *****.\n"; + cerr << getTime() << "RADIUS-PLUGIN: Build password packet: password: *****, sharedSecret: *****.\n"; //add the attributes ra2.setValue(this->password); if(packet.addRadiusAttribute(&ra1)) { - fprintf(stderr, "RADIUS-PLUGIN: Fail to add attribute ATTRIB_User_Name.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Fail to add attribute ATTRIB_User_Name.\n"; } if (packet.addRadiusAttribute(&ra2)) { - fprintf(stderr, "RADIUS-PLUGIN: Fail to add attribute ATTRIB_User_Password.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Fail to add attribute ATTRIB_User_Password.\n"; } if (packet.addRadiusAttribute(&ra3)) { - fprintf(stderr, "RADIUS-PLUGIN: Fail to add attribute ATTRIB_NAS_Port.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Fail to add attribute ATTRIB_NAS_Port.\n"; } if (packet.addRadiusAttribute(&ra4)) { - fprintf(stderr, "RADIUS-PLUGIN: Fail to add attribute ATTRIB_Calling_Station_Id.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Fail to add attribute ATTRIB_Calling_Station_Id.\n"; } //get information from the config and add it to the packet if(strcmp(context->radiusconf.getNASIdentifier(),"")) @@ -97,7 +97,7 @@ int UserAuth::sendAcceptRequestPacket(PluginContext * context) ra5.setValue(context->radiusconf.getNASIdentifier()); if (packet.addRadiusAttribute(&ra5)) { - fprintf(stderr, "RADIUS-PLUGIN: Fail to add attribute ATTRIB_NAS_Identifier.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Fail to add attribute ATTRIB_NAS_Identifier.\n"; } } @@ -105,12 +105,12 @@ int UserAuth::sendAcceptRequestPacket(PluginContext * context) { if(ra6.setValue(context->radiusconf.getNASIpAddress())!=0) { - fprintf(stderr, "RADIUS-PLUGIN: Fail to set value ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Fail to set value ATTRIB_NAS_Ip_Address.\n"; } else if (packet.addRadiusAttribute(&ra6)) { - fprintf(stderr, "RADIUS-PLUGIN: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Fail to add attribute ATTRIB_NAS_Ip_Address.\n"; } } if(strcmp(context->radiusconf.getNASPortType(),"")) @@ -118,7 +118,7 @@ int UserAuth::sendAcceptRequestPacket(PluginContext * context) ra7.setValue(context->radiusconf.getNASPortType()); if (packet.addRadiusAttribute(&ra7)) { - fprintf(stderr, "RADIUS-PLUGIN: Fail to add attribute ATTRIB_NAS_Port_Type.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Fail to add attribute ATTRIB_NAS_Port_Type.\n"; } } @@ -127,27 +127,27 @@ int UserAuth::sendAcceptRequestPacket(PluginContext * context) ra8.setValue(context->radiusconf.getServiceType()); if (packet.addRadiusAttribute(&ra8)) { - fprintf(stderr, "RADIUS-PLUGIN: Fail to add attribute ATTRIB_Service_Type.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Fail to add attribute ATTRIB_Service_Type.\n"; } } if(this->getFramedIp().compare("") != 0) { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Send packet Re-Auth packet for framedIP=%s.\n",this->getFramedIp().c_str()); + cerr << getTime() << "RADIUS-PLUGIN: Send packet Re-Auth packet for framedIP="<< this->getFramedIp().c_str() << ".\n"; ra9.setValue(this->getFramedIp()); if (packet.addRadiusAttribute(&ra9)) { - fprintf(stderr, "RADIUS-PLUGIN: Fail to add attribute Framed-IP-Address.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Fail to add attribute Framed-IP-Address.\n"; } } if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Send packet to %s.\n",server->getName().c_str()); + cerr << getTime() << "RADIUS-PLUGIN: Send packet to " << server->getName().c_str() <<".\n"; //send the packet if (packet.radiusSend(server)<0) { - fprintf(stderr, "RADIUS-PLUGIN: Packet was not send.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Packet was not send.\n"; } //receive the packet if (packet.radiusReceive(serverlist)==0) @@ -156,7 +156,7 @@ int UserAuth::sendAcceptRequestPacket(PluginContext * context) if(packet.getCode()==ACCESS_ACCEPT) { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Get ACCESS_ACCEPT-Packet.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Get ACCESS_ACCEPT-Packet.\n"; //parse the attributes for framedip, framedroutes and //acctinteriminterval @@ -166,14 +166,14 @@ int UserAuth::sendAcceptRequestPacket(PluginContext * context) } else { - fprintf (stderr, "RADIUS-PLUGIN: Get ACCESS_REJECT or ACCESS_CHALLANGE-Packet.->ACCESS-DENIED.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Get ACCESS_REJECT or ACCESS_CHALLANGE-Packet.->ACCESS-DENIED.\n"; return 1; } } else { - fprintf (stderr, "RADIUS-PLUGIN: Got no response from radius server.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Got no response from radius server.\n"; } return 1; @@ -195,7 +195,7 @@ void UserAuth::parseResponsePacket(RadiusPacket *packet, PluginContext * context RadiusVendorSpecificAttribute vsa; if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: parse_response_packet().\n"); + cerr << getTime() << "RADIUS-PLUGIN: parse_response_packet().\n"; @@ -215,7 +215,7 @@ void UserAuth::parseResponsePacket(RadiusPacket *packet, PluginContext * context if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND AUTH: routes: " << this->getFramedRoutes() <<".\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: routes: " << this->getFramedRoutes() <<".\n"; range=packet->findAttributes(8); @@ -229,7 +229,7 @@ void UserAuth::parseResponsePacket(RadiusPacket *packet, PluginContext * context } if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND AUTH: framed ip: " << this->getFramedIp() <<".\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: framed ip: " << this->getFramedIp() <<".\n"; @@ -242,11 +242,11 @@ void UserAuth::parseResponsePacket(RadiusPacket *packet, PluginContext * context } else { - fprintf(stderr,"RADIUS-PLUGIN: No attributes Acct Interim Interval or bad length.\n"); + cerr << getTime() <<"RADIUS-PLUGIN: No attributes Acct Interim Interval or bad length.\n"; } if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: BACKGROUND AUTH: Acct Interim Interval: " << this->getAcctInterimInterval() << ".\n"; + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: Acct Interim Interval: " << this->getAcctInterimInterval() << ".\n"; range=packet->findAttributes(26); iter1=range.first; @@ -1438,7 +1438,7 @@ string UserAuth::valueToString(RadiusVendorSpecificAttribute *vsa) } else { - cerr << "Vendor Specific Attribute (Id: " << vsa->getId() << " Type: " << vsa->getType() << " not implemented, treated as string."; + cerr << getTime() << "Vendor Specific Attribute (Id: " << vsa->getId() << " Type: " << vsa->getType() << " not implemented, treated as string."; return vsa->stringFromBuf(); } @@ -1484,13 +1484,13 @@ int UserAuth::createCcdFile(PluginContext *context) if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND AUTH: Try to open ccd file.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: Try to open ccd file.\n"; //open the file ccdfile.open(filename.c_str(),ios::out); if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGROUND AUTH: Opened ccd file.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGROUND AUTH: Opened ccd file.\n"; // copy in a temp-string, becaue strtok deletes the delimiter, if it used anywhere @@ -1504,7 +1504,7 @@ int UserAuth::createCcdFile(PluginContext *context) if (this->framedip[0]!='\0') { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGORUND AUTH: Write framed ip to ccd-file.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGORUND AUTH: Write framed ip to ccd-file.\n"; //build the ifconfig strncat(ipstring, "ifconfig-push ",14); @@ -1516,14 +1516,14 @@ int UserAuth::createCcdFile(PluginContext *context) { strncat(ipstring, context->conf.getSubnet() , 15); if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGORUND AUTH: Create ifconfig-push for topology subnet.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGORUND AUTH: Create ifconfig-push for topology subnet.\n"; } else if(context->conf.getP2p()[0]!='\0') { strncat(ipstring, context->conf.getP2p() , 15); if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGORUND AUTH: Create ifconfig-push for topology p2p.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGORUND AUTH: Create ifconfig-push for topology p2p.\n"; } else @@ -1543,11 +1543,11 @@ int UserAuth::createCcdFile(PluginContext *context) // append the new ip address to the string strncat(ipstring, inet_ntoa(ip3), 15); if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGORUND AUTH: Create ifconfig-push for topology net30.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGORUND AUTH: Create ifconfig-push for topology net30.\n"; } if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Write %s ccd-file.\n",ipstring); + cerr << getTime() << "RADIUS-PLUGIN: Write " << ipstring << " ccd-file.\n"; ccdfile << ipstring <<"\n"; @@ -1557,13 +1557,13 @@ int UserAuth::createCcdFile(PluginContext *context) if (framedroutes[0]!='\0') { if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: BACKGORUND AUTH: Write framed routes to ccd-file.\n"); + cerr << getTime() << "RADIUS-PLUGIN: BACKGORUND AUTH: Write framed routes to ccd-file.\n"; route=strtok(framedroutes,";"); len=strlen(route); if (len > 50) //this is to big!! but the length is variable { - fprintf(stderr,"RADIUS-PLUGIN: Argument for Framed Route is to long (>100 Characters).\n"); + cerr << getTime() <<"RADIUS-PLUGIN: Argument for Framed Route is to long (>100 Characters).\n"; return 1; } else @@ -1649,7 +1649,7 @@ int UserAuth::createCcdFile(PluginContext *context) memset(framednetmask,0,16); if (atoi(framednetmask_cidr)>32) { - fprintf(stderr, "RADIUS-PLUGIN: Bad net CIDR netmask.\n"); + cerr << getTime() << "RADIUS-PLUGIN: Bad net CIDR netmask.\n"; } else { @@ -1719,7 +1719,7 @@ int UserAuth::createCcdFile(PluginContext *context) } if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Write route string: %s %s %s to ccd-file.\n","iroute " ,framedip, framednetmask); + cerr << getTime() << "RADIUS-PLUGIN: Write route string: iroute " << framedip << framednetmask << " to ccd-file.\n"; //write iroute to client file ccdfile << "iroute " << framedip << " "<< framednetmask << "\n"; @@ -1733,13 +1733,13 @@ int UserAuth::createCcdFile(PluginContext *context) } else { - cerr << "RADIUS-PLUGIN: Could not open file "<< filename << "\n."; + cerr << getTime() << "RADIUS-PLUGIN: Could not open file "<< filename << ".\n"; return 1; } } else { - cerr << "RADIUS-PLUGIN: Client config file was not written, overwriteccfiles is false \n."; + cerr << getTime() << "RADIUS-PLUGIN: Client config file was not written, overwriteccfiles is false \n."; } return 0; diff --git a/UserPlugin.cpp b/UserPlugin.cpp index 84128e5..31b68da 100755 --- a/UserPlugin.cpp +++ b/UserPlugin.cpp @@ -28,6 +28,7 @@ UserPlugin::UserPlugin() : User() { this->accounted=false; this->authenticated=false; + this->authcontrolfile=""; } /**The destructor, nothing happens here.*/ @@ -49,6 +50,7 @@ UserPlugin & UserPlugin::operator=(const UserPlugin &u) this->sessionid=u.sessionid; this->password=u.password; this->untrustedport=u.untrustedport; + this->authcontrolfile=u.authcontrolfile; } return *this; @@ -75,6 +77,7 @@ UserPlugin::UserPlugin(const UserPlugin &u) : User(u) this->authenticated=u.authenticated; this->accounted=u.accounted; this->untrustedport=u.untrustedport; + this->authcontrolfile=u.authcontrolfile; } /**The getter method of the password. @@ -136,4 +139,14 @@ void UserPlugin::setAccounted(bool acct) this->accounted=acct; } +string UserPlugin::getAuthControlFile(void ) +{ + return authcontrolfile; +} + +void UserPlugin::setAuthControlFile(string file) +{ + authcontrolfile=file; +} + diff --git a/UserPlugin.h b/UserPlugin.h index b10488a..a58c3d7 100755 --- a/UserPlugin.h +++ b/UserPlugin.h @@ -37,6 +37,7 @@ class UserPlugin : public User private: string password; /** - * - * 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 - */ - -// This file is the original from OpenVPN. - /* * OpenVPN -- An application to securely tunnel IP networks * over a single TCP/UDP port, with support for SSL/TLS-based @@ -28,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2005 OpenVPN Solutions LLC + * Copyright (C) 2002-2008 OpenVPN Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -45,9 +22,68 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define OPENVPN_PLUGIN_VERSION 2 + /* * Plug-in types. These types correspond to the set of script callbacks * supported by OpenVPN. + * + * This is the general call sequence to expect when running in server mode: + * + * Initial Server Startup: + * + * FUNC: openvpn_plugin_open_v1 + * FUNC: openvpn_plugin_client_constructor_v1 (this is the top-level "generic" + * client template) + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_UP + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_ROUTE_UP + * + * New Client Connection: + * + * FUNC: openvpn_plugin_client_constructor_v1 + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_VERIFY (called once for every cert + * in the server chain) + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_FINAL + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_IPCHANGE + * + * [If OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY returned OPENVPN_PLUGIN_FUNC_DEFERRED, + * we don't proceed until authentication is verified via auth_control_file] + * + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_CLIENT_CONNECT_V2 + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_LEARN_ADDRESS + * + * [Client session ensues] + * + * For each "TLS soft reset", according to reneg-sec option (or similar): + * + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_ENABLE_PF + * + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_VERIFY (called once for every cert + * in the server chain) + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_TLS_FINAL + * + * [If OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY returned OPENVPN_PLUGIN_FUNC_DEFERRED, + * we expect that authentication is verified via auth_control_file within + * the number of seconds defined by the "hand-window" option. Data channel traffic + * will continue to flow uninterrupted during this period.] + * + * [Client session continues] + * + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_CLIENT_DISCONNECT + * FUNC: openvpn_plugin_client_constructor_v1 + * + * [ some time may pass ] + * + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_LEARN_ADDRESS (this coincides with a + * lazy free of initial + * learned addr object) + * Server Shutdown: + * + * FUNC: openvpn_plugin_func_v1 OPENVPN_PLUGIN_DOWN + * FUNC: openvpn_plugin_client_destructor_v1 (top-level "generic" client) + * FUNC: openvpn_plugin_close_v1 */ #define OPENVPN_PLUGIN_UP 0 #define OPENVPN_PLUGIN_DOWN 1 @@ -58,7 +94,10 @@ #define OPENVPN_PLUGIN_CLIENT_CONNECT 6 #define OPENVPN_PLUGIN_CLIENT_DISCONNECT 7 #define OPENVPN_PLUGIN_LEARN_ADDRESS 8 -#define OPENVPN_PLUGIN_N 9 +#define OPENVPN_PLUGIN_CLIENT_CONNECT_V2 9 +#define OPENVPN_PLUGIN_TLS_FINAL 10 +#define OPENVPN_PLUGIN_ENABLE_PF 11 +#define OPENVPN_PLUGIN_N 12 /* * Build a mask out of a set of plug-in types. @@ -76,6 +115,7 @@ typedef void *openvpn_plugin_handle_t; */ #define OPENVPN_PLUGIN_FUNC_SUCCESS 0 #define OPENVPN_PLUGIN_FUNC_ERROR 1 +#define OPENVPN_PLUGIN_FUNC_DEFERRED 2 /* * For Windows (needs to be modified for MSVC) @@ -108,6 +148,22 @@ typedef void *openvpn_plugin_handle_t; #endif +/* + * Used by openvpn_plugin_func to return structured + * data. The plugin should allocate all structure + * instances, name strings, and value strings with + * malloc, since OpenVPN will assume that it + * can free the list by calling free() over the same. + */ +extern "C"{ +struct openvpn_plugin_string_list +{ + struct openvpn_plugin_string_list *next; + char *name; + char *value; +}; + + /* * Multiple plugin modules can be cascaded, and modules can be * used in tandem with scripts. The order of operation is that @@ -118,19 +174,27 @@ typedef void *openvpn_plugin_handle_t; * function (such as tls-verify or auth-user-pass-verify), then * every module and script must return success (0) in order for * the connection to be authenticated. + * + * Notes: + * + * Plugins which use a privilege-separation model (by forking in + * their initialization function before the main OpenVPN process + * downgrades root privileges and/or executes a chroot) must + * daemonize after a fork if the "daemon" environmental variable is + * set. In addition, if the "daemon_log_redirect" variable is set, + * the plugin should preserve stdout/stderr across the daemon() + * syscall. See the daemonize() function in plugin/auth-pam/auth-pam.c + * for an example. */ -extern "C" -{ - - - /* * Prototypes for functions which OpenVPN plug-ins must define. */ /* - * FUNCTION: openvpn_plugin_open_v1 + * FUNCTION: openvpn_plugin_open_v2 + * + * REQUIRED: YES * * Called on initial plug-in load. OpenVPN will preserve plug-in state * across SIGUSR1 restarts but not across SIGHUP restarts. A SIGHUP reset @@ -156,22 +220,30 @@ extern "C" * these variables are not actually written to the "official" * environmental variable store of the process. * + * return_list : used to return data back to OpenVPN. + * * RETURN VALUE * * An openvpn_plugin_handle_t value on success, NULL on failure */ -OPENVPN_PLUGIN_DEF openvpn_plugin_handle_t OPENVPN_PLUGIN_FUNC(openvpn_plugin_open_v1) - (unsigned int *type_mask, const char *argv[], const char *envp[]); + +OPENVPN_PLUGIN_DEF openvpn_plugin_handle_t OPENVPN_PLUGIN_FUNC(openvpn_plugin_open_v2) + (unsigned int *type_mask, + const char *argv[], + const char *envp[], + struct openvpn_plugin_string_list **return_list); /* - * FUNCTION: openvpn_plugin_func_v1 + * FUNCTION: openvpn_plugin_func_v2 * * Called to perform the work of a given script type. * + * REQUIRED: YES + * * ARGUMENTS * - * context : the openvpn_plugin_handle_t value which was returned by - * openvpn_plugin_open_v1. + * handle : the openvpn_plugin_handle_t value which was returned by + * openvpn_plugin_open. * * type : one of the PLUGIN_x types * @@ -184,24 +256,210 @@ OPENVPN_PLUGIN_DEF openvpn_plugin_handle_t OPENVPN_PLUGIN_FUNC(openvpn_plugin_op * these variables are not actually written to the "official" * environmental variable store of the process. * + * per_client_context : the per-client context pointer which was returned by + * openvpn_plugin_client_constructor_v1, if defined. + * + * return_list : used to return data back to OpenVPN. + * * RETURN VALUE * * OPENVPN_PLUGIN_FUNC_SUCCESS on success, OPENVPN_PLUGIN_FUNC_ERROR on failure + * + * In addition, OPENVPN_PLUGIN_FUNC_DEFERRED may be returned by + * OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY. This enables asynchronous + * authentication where the plugin (or one of its agents) may indicate + * authentication success/failure some number of seconds after the return + * of the OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY handler by writing a single + * char to the file named by auth_control_file in the environmental variable + * list (envp). + * + * first char of auth_control_file: + * '0' -- indicates auth failure + * '1' -- indicates auth success + * + * OpenVPN will delete the auth_control_file after it goes out of scope. + * + * If an OPENVPN_PLUGIN_ENABLE_PF handler is defined and returns success + * for a particular client instance, packet filtering will be enabled for that + * instance. OpenVPN will then attempt to read the packet filter configuration + * from the temporary file named by the environmental variable pf_file. This + * file may be generated asynchronously and may be dynamically updated during the + * client session, however the client will be blocked from sending or receiving + * VPN tunnel packets until the packet filter file has been generated. OpenVPN + * will periodically test the packet filter file over the life of the client + * instance and reload when modified. OpenVPN will delete the packet filter file + * when the client instance goes out of scope. + * + * Packet filter file grammar: + * + * [CLIENTS DROP|ACCEPT] + * {+|-}common_name1 + * {+|-}common_name2 + * . . . + * [SUBNETS DROP|ACCEPT] + * {+|-}subnet1 + * {+|-}subnet2 + * . . . + * [END] + * + * Subnet: IP-ADDRESS | IP-ADDRESS/NUM_NETWORK_BITS + * + * CLIENTS refers to the set of clients (by their common-name) which + * this instance is allowed ('+') to connect to, or is excluded ('-') + * from connecting to. Note that in the case of client-to-client + * connections, such communication must be allowed by the packet filter + * configuration files of both clients. + * + * SUBNETS refers to IP addresses or IP address subnets which this + * instance may connect to ('+') or is excluded ('-') from connecting + * to. + * + * DROP or ACCEPT defines default policy when there is no explicit match + * for a common-name or subnet. The [END] tag must exist. A special + * purpose tag called [KILL] will immediately kill the client instance. + * A given client or subnet rule applies to both incoming and outgoing + * packets. + * + * See plugin/defer/simple.c for an example on using asynchronous + * authentication and client-specific packet filtering. */ -OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_func_v1) - (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]); +OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_func_v2) + (openvpn_plugin_handle_t handle, + const int type, + const char *argv[], + const char *envp[], + void *per_client_context, + struct openvpn_plugin_string_list **return_list); /* * FUNCTION: openvpn_plugin_close_v1 * + * REQUIRED: YES + * * ARGUMENTS * - * context : the openvpn_plugin_handle_t value which was returned by - * openvpn_plugin_open_v1. + * handle : the openvpn_plugin_handle_t value which was returned by + * openvpn_plugin_open. * * Called immediately prior to plug-in unload. */ + OPENVPN_PLUGIN_DEF void OPENVPN_PLUGIN_FUNC(openvpn_plugin_close_v1) (openvpn_plugin_handle_t handle); - -} //end extern C +} +/* + * FUNCTION: openvpn_plugin_abort_v1 + * + * REQUIRED: NO + * + * ARGUMENTS + * + * handle : the openvpn_plugin_handle_t value which was returned by + * openvpn_plugin_open. + * + * Called when OpenVPN is in the process of aborting due to a fatal error. + * Will only be called on an open context returned by a prior successful + * openvpn_plugin_open callback. + */ +OPENVPN_PLUGIN_DEF void OPENVPN_PLUGIN_FUNC(openvpn_plugin_abort_v1) + (openvpn_plugin_handle_t handle); + +/* + * FUNCTION: openvpn_plugin_client_constructor_v1 + * + * Called to allocate a per-client memory region, which + * is then passed to the openvpn_plugin_func_v2 function. + * This function is called every time the OpenVPN server + * constructs a client instance object, which normally + * occurs when a session-initiating packet is received + * by a new client, even before the client has authenticated. + * + * This function should allocate the private memory needed + * by the plugin to track individual OpenVPN clients, and + * return a void * to this memory region. + * + * REQUIRED: NO + * + * ARGUMENTS + * + * handle : the openvpn_plugin_handle_t value which was returned by + * openvpn_plugin_open. + * + * RETURN VALUE + * + * void * pointer to plugin's private per-client memory region, or NULL + * if no memory region is required. + */ +OPENVPN_PLUGIN_DEF void * OPENVPN_PLUGIN_FUNC(openvpn_plugin_client_constructor_v1) + (openvpn_plugin_handle_t handle); + +/* + * FUNCTION: openvpn_plugin_client_destructor_v1 + * + * This function is called on client instance object destruction. + * + * REQUIRED: NO + * + * ARGUMENTS + * + * handle : the openvpn_plugin_handle_t value which was returned by + * openvpn_plugin_open. + * + * per_client_context : the per-client context pointer which was returned by + * openvpn_plugin_client_constructor_v1, if defined. + */ + +OPENVPN_PLUGIN_DEF void OPENVPN_PLUGIN_FUNC(openvpn_plugin_client_destructor_v1) + (openvpn_plugin_handle_t handle, void *per_client_context); + +/* + * FUNCTION: openvpn_plugin_select_initialization_point_v1 + * + * Several different points exist in OpenVPN's initialization sequence where + * the openvpn_plugin_open function can be called. While the default is + * OPENVPN_PLUGIN_INIT_PRE_DAEMON, this function can be used to select a + * different initialization point. For example, if your plugin needs to + * return configuration parameters to OpenVPN, use + * OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE. + * + * REQUIRED: NO + * + * RETURN VALUE: + * + * An OPENVPN_PLUGIN_INIT_x value. + */ +#define OPENVPN_PLUGIN_INIT_PRE_CONFIG_PARSE 1 +#define OPENVPN_PLUGIN_INIT_PRE_DAEMON 2 /* default */ +#define OPENVPN_PLUGIN_INIT_POST_DAEMON 3 +#define OPENVPN_PLUGIN_INIT_POST_UID_CHANGE 4 + +OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_select_initialization_point_v1) + (void); + +/* + * FUNCTION: openvpn_plugin_min_version_required_v1 + * + * This function is called by OpenVPN to query the minimum + plugin interface version number required by the plugin. + * + * REQUIRED: NO + * + * RETURN VALUE + * + * The minimum OpenVPN plugin interface version number necessary to support + * this plugin. + */ +OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_min_version_required_v1) + (void); + +/* + * Deprecated functions which are still supported for backward compatibility. + */ + +OPENVPN_PLUGIN_DEF openvpn_plugin_handle_t OPENVPN_PLUGIN_FUNC(openvpn_plugin_open_v1) + (unsigned int *type_mask, + const char *argv[], + const char *envp[]); + +OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_func_v1) + (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]); diff --git a/radiusplugin.cnf b/radiusplugin.cnf index 9bdf847..83ca0fb 100755 --- a/radiusplugin.cnf +++ b/radiusplugin.cnf @@ -52,7 +52,7 @@ server # The UDP port for radius authentication. authport=1812 # The name or ip address of the radius server. - name=127.0.0.1 + name=192.168.0.153 # How many times should the plugin send the if there is no response? retry=1 # How long should the plugin wait for a response? diff --git a/radiusplugin.cpp b/radiusplugin.cpp index ee95b1e..ee9172c 100755 --- a/radiusplugin.cpp +++ b/radiusplugin.cpp @@ -1,7 +1,7 @@ /* - * radiusplugin -- An OpenVPN plugin for do radius authentication + * radiusplugin -- An OpenVPN plugin for do radius authentication * and accounting. - * + * * Copyright (C) 2005 EWE TEL GmbH/Ralf Luebben * * This program is free software; you can redistribute it and/or modify @@ -18,864 +18,793 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - //The callback functions of the plugin infrastructure. + +//The callback functions of the plugin infrastructure. #include "radiusplugin.h" -//define extern "C", so the c++ compiler generate a shared library +//define extern "C", so the c++ compiler generate a shared library //which is compatible with c programms extern "C" { - -/** The function is needed by the OpenVpn plugin model. The funtion is called - * when OpenVpn starts. In this case here two background process are - * started. One for authentication and one for accounting. The communication - * between the processes is made via sockets. - * You need a background process for accounting, because the interval - * in which accounting information is sent to the radius server in undependent - * from the main OpenVpn-process, so it is done by another process which schedule - * the accounting intervals. This process holds his root rights and it can set and - * deletes routes in the system routing table. - * The authentication process is a own process, too. So there is clear separation - * and it is undependent from the openvpn process. - * @param The type of plugin, maybe client_connect, client_disconnect, user_auth_pass_verify... - * @param A list of arguments which are set in the configuration file of openvpn in plugin line. - * @param The list of enviromental variables, it is created by the OpenVpn-Process. - */ -OPENVPN_EXPORT openvpn_plugin_handle_t -openvpn_plugin_open_v1(unsigned int *type_mask, const char *argv[], const char *envp[]) -{ - pid_t pid; /**setVerbosity(atoi(verb_string)); - - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Start AUTH-RADIUS-PLUGIN\n"); - - - // Make sure we have one string argument: the .so name. - if (string_array_len (argv) < base_parms) - { - fprintf (stderr, "RADIUS-PLUGIN: no .so name\n"); - goto error; - } - - - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Found %i params.\n", string_array_len (argv)); - - - // See if we have optional name/value pairs for - // the plugin, this can only be the config file. - // path (default: -c /etc/openvpn/radiusplugin.conf) - name_value_list.len = 0; - if (string_array_len (argv) > base_parms) - { - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Find params.\n"); - - //just a work around because argv[1] is the filename - name_value_list.data[0].name = "-c"; - name_value_list.data[0].value = argv[1]; - - if (strncmp(name_value_list.data[0].name,"-c",2)==0) - { - //see in ./RadiusClass/error.h for errornumbers - //parse the radiusplugin config file - fprintf (stderr, "RADIUS-PLUGIN: Configfile name: %s .\n", name_value_list.data[0].value); - if (context->radiusconf.parseConfigFile(name_value_list.data[0].value)!=0 or context->conf.parseConfigFile(name_value_list.data[0].value)!=0) - { - fprintf (stderr, "RADIUS-PLUGIN: Bad config file or error in config.\n"); - goto error; - } - - - } - else - { - fprintf (stderr, "RADIUS-PLUGIN: Bad argument for plugin.\n"); - goto error; - } - - } - else - { - //if there is no filename, use the default - //parse the radiusplugin config file - fprintf (stderr, "RADIUS-PLUGIN: Configfile name: /etc/openvpn/radiusplugin.cnf.\n"); - if (context->radiusconf.parseConfigFile("/etc/openvpn/radiusplugin.cnf")!=0 or context->conf.parseConfigFile("/etc/openvpn/radiusplugin.cnf")!=0) - { - fprintf (stderr, "RADIUS-PLUGIN: Bad config file or error in config.\n"); - goto error; - } - - } - - // Make a socket for foreground and background processes - // to communicate. - //Authentication process: - if (socketpair (PF_UNIX, SOCK_DGRAM, 0, fd_auth) == -1) - { - fprintf (stderr, "RADIUS-PLUGIN: socketpair call failed for authentication process\n"); - goto error; - } - //Accounting process: - if (socketpair (PF_UNIX, SOCK_DGRAM, 0, fd_acct) == -1) - { - fprintf (stderr, "RADIUS-PLUGIN: socketpair call failed for accounting process\n"); - goto error; - } - - - // Fork off the privileged processes. It will remain privileged - // even after the foreground process drops its privileges. - - - // Fork the authentication process - pid = fork (); - if (pid) - { - // Foreground Process (Parent) - int status; - - //save the process id - context->setAuthPid(pid); - - // close our copy of child's socket - close (fd_auth[1]); - - /* don't let future subprocesses inherit child socket */ - if (fcntl (fd_auth[0], F_SETFD, FD_CLOEXEC) < 0) - fprintf (stderr, "RADIUS-PLUGIN: Set FD_CLOEXEC flag on socket file descriptor failed\n"); - - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Start BACKGROUND Process for authentication with PID %i\n", context->getAuthPid()); - - //save the socket number in the context - context->authsocketbackgr.setSocket(fd_auth[0]); - - //wait for background child process to initialize */ - status = context->authsocketbackgr.recvInt(); - - if (status != RESPONSE_INIT_SUCCEEDED) + + //OPENVPN_EXPORT openvpn_plugin_handle_t + //openvpn_plugin_open_v1 ( unsigned int *type_mask, const char *argv[], const char *envp[] ) + OPENVPN_PLUGIN_DEF openvpn_plugin_handle_t OPENVPN_PLUGIN_FUNC(openvpn_plugin_open_v2)(unsigned int *type_mask, + const char *argv[], + const char *envp[], + struct openvpn_plugin_string_list **return_list) + { + pid_t pid; /**setVerbosity ( atoi ( verb_string ) ); + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: Start AUTH-RADIUS-PLUGIN\n"; + + + // Make sure we have one string argument: the .so name. + if ( string_array_len ( argv ) < base_parms ) { - //set the socket to -1 if the initialization failed - context->authsocketbackgr.setSocket(-1); + cerr << getTime() << "RADIUS-PLUGIN: no .so name\n"; + goto error; } - - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Start AUTH-RADIUS-PLUGIN\n"); - } - else - { - - //Background Process - - // close all parent fds except our socket back to parent - close_fds_except (fd_auth[1]); - - // Ignore most signals (the parent will receive them) - set_signals (); - - //save the socket number in the context - context->authsocketforegr.setSocket(fd_auth[1]); - - //start the backgroung event loop for accounting - Auth.Authentication(context); - - //close the socket - close (fd_auth[1]); - - //free the context of the background process - delete context; - - exit (0); - return 0; // NOTREACHED - } - - // Fork the accounting process - pid = fork (); - if (pid) - { - // Foreground Process (Parent) - int status; //status if the background process - - //save the pid - context->setAcctPid(pid); - - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Start BACKGROUND Process for accounting with PID %i\n", context->getAcctPid()); - - // close our copy of child's socket */ - close (fd_acct[1]); - - /* don't let future subprocesses inherit child socket */ - if (fcntl (fd_acct[0], F_SETFD, FD_CLOEXEC) < 0) - fprintf (stderr, "RADIUS-PLUGIN: Set FD_CLOEXEC flag on socket file descriptor failed\n"); - - //save the socket number in the context - context->acctsocketbackgr.setSocket(fd_acct[0]); - - // wait for background child process to initialize */ - status = context->acctsocketbackgr.recvInt(); - - if (status != RESPONSE_INIT_SUCCEEDED) + + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: Found "<< string_array_len ( argv ) << " params.\n"; + + + // See if we have optional name/value pairs for + // the plugin, this can only be the config file. + // path (default: -c /etc/openvpn/radiusplugin.conf) + name_value_list.len = 0; + if ( string_array_len ( argv ) > base_parms ) { - //set the socket to -1 if the initialization failed - context->acctsocketbackgr.setSocket(-1); - } - - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Start AUTH-RADIUS-PLUGIN\n"); - } - else - { - - //Background Process - - // close all parent fds except our socket back to parent - close_fds_except (fd_acct[1]); - - // Ignore most signals (the parent will receive them) - set_signals (); - - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: Start BACKGROUND Process for accounting\n"); - - // save the socket in the context - context->acctsocketforegr.setSocket(fd_acct[1]); - - //start the backgroung event loop for accounting - Acct.Accounting(context); - - //close the socket - close (fd_acct[1]); - - //free the context of the background process - delete context; - exit (0); - return 0; // NOTREACHED - } - - //return the context, this is used between the functions - //openvpn_plugin_open_v1 - //openvpn_plugin_func_v1 - //openvpn_plugin_close_v1 - return (openvpn_plugin_handle_t) context; - - error: - //delete the context - if (context) - delete (context); - return NULL; -} + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: Find params.\n"; + //just a work around because argv[1] is the filename + name_value_list.data[0].name = "-c"; + name_value_list.data[0].value = argv[1]; -/** This funtion is called from the OpenVpn process everytime - * a event happens. The function handle the events (plugins) - * AUTH_USER_PASS_VERIFY, CLIENT_CONNECT, CLIENT_DISCONNECT. - * The function reads the information from the envriomental - * variable and sends the relevant information to the - * background processes. - * AUTH_USER_PASS_VERIFY: The user is authenticated by a radius server, - * if it succeeded the background sends back the framed ip, the routes and the acct_interim_interval - * for the user. Than the user is added to the context. - * CLIENT_CONNECT: The user is added to the accounting by - * sending the information to the background process. - * CLIENT_DISCONNECT: The user is deleted from the - * accounting by sending the information to the backgrund process. - * @param The handle which was allocated in the open function. - * @param The type of plugin, maybe client_conect, client_disconnect, auth_user_pass_verify - * @param A list of arguments which are set in the openvpn configuration file. - * @param The list of enviromental variables, it is created by the OpenVpn-Process. - * @return A interger with the status of the funtion (OPENVPN_PLUGIN_FUNC_SUCCESS or OPENVPN_PLUGIN_FUNC_ERROR). - */ -OPENVPN_EXPORT int -openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]) -{ - //restore the context which was created at the function openvpn_plugin_open_v1 - PluginContext *context = (struct PluginContext *) handle; - - UserPlugin *newuser=NULL; /**< A context for an new user.*/ - UserPlugin *olduser=NULL; /**authsocketbackgr.getSocket()) >= 0) - { - - if (DEBUG (context->getVerbosity())) - { - cerr << "RADIUS-PLUGIN: FOREGROUND: OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY is called.\n"; - } - //create a new user - newuser=new UserPlugin(); - - //allocate the memory, don't care about the value - try - { - if (get_env ("username", envp)==NULL) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: username is not defined\n"); - } - else if (get_env ("password", envp)==NULL) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: password is not defined\n"); - } - else if (get_env ("untrusted_ip", envp)==NULL && get_env ("untrusted_ip6", envp)==NULL) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: untrusted_ip and untrusted_ip6 is not defined\n"); - } - else if (get_env ("common_name", envp)==NULL) - { - if (context->conf.getClientCertNotRequired() == false) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: common_name is not defined\n"); - } - } - else if (get_env ("untrusted_port", envp)==NULL) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: untrusted_port is not defined\n"); - } - - - // get username, password, unrusted_ip and common_name from envp string array - newuser->setUsername(get_env ("username", envp)); - newuser->setPassword(get_env ("password", envp)); - - // it's ipv4 - if(get_env ("untrusted_ip", envp)!=NULL) + if ( strncmp ( name_value_list.data[0].name,"-c",2 ) ==0 ) { - untrusted_ip = get_env ("untrusted_ip", envp); + //see in ./RadiusClass/error.h for errornumbers + //parse the radiusplugin config file + cerr << getTime() << "RADIUS-PLUGIN: Configfile name: "<< name_value_list.data[0].value << ".\n"; + if ( context->radiusconf.parseConfigFile ( name_value_list.data[0].value ) !=0 or context->conf.parseConfigFile ( name_value_list.data[0].value ) !=0 ) + { + cerr << getTime() << "RADIUS-PLUGIN: Bad config file or error in config.\n"; + goto error; + } + + } - // it's ipv6 else { - untrusted_ip = get_env ("untrusted_ip6", envp); + cerr << getTime() << "RADIUS-PLUGIN: Bad argument for plugin.\n"; + goto error; } - newuser->setCallingStationId(untrusted_ip); - //for OpenVPN option client cert not required, common_name is "UNDEF", see status.log - - if (get_env ("common_name", envp)!=NULL) - { - newuser->setCommonname(get_env ("common_name", envp)); - } - //rewrite the username if OpenVPN use the option username-as-comon-name - - - if(context->conf.getUsernameAsCommonname() == true) - { - if (DEBUG (context->getVerbosity())) cerr << "RADIUS-PLUGIN: FOREGROUND: Commonname set to Username\n"; - newuser->setCommonname(get_env ("username", envp)); - } - - - newuser->setUntrustedPort(get_env("untrusted_port", envp)); - newuser->setKey(newuser->getCommonname() +string(",") + untrusted_ip + string(":") + get_env ("untrusted_port", envp)); - - //is the user already known? - olduser=context->findUser(newuser->getKey()); - - //the user is already authenticated if an olduser is found and the ip address and the port the same => it is a renegotiation - //OLD statement if(olduser!=NULL && (olduser->getCallingStationId().compare(newuser->getCallingStationId())==0) && (olduser->getUntrustedPort().compare(newuser->getUntrustedPort())==0)) - if(olduser!=NULL) // is already in unique key of the user ->&& (olduser->getCallingStationId().compare(newuser->getCallingStationId())==0) && (olduser->getUntrustedPort().compare(newuser->getUntrustedPort())==0)) + + } + else + { + //if there is no filename, use the default + //parse the radiusplugin config file + cerr << getTime() << "RADIUS-PLUGIN: Configfile name: /etc/openvpn/radiusplugin.cnf.\n"; + if ( context->radiusconf.parseConfigFile ( "/etc/openvpn/radiusplugin.cnf" ) !=0 or context->conf.parseConfigFile ( "/etc/openvpn/radiusplugin.cnf" ) !=0 ) { - if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: FOREGROUND: Renegotiation: username: "<< newuser->getUsername() - << "\nRADIUS-PLUGIN: FOREGROUND:\t olduser ip: " << olduser->getCallingStationId() - << "\nRADIUS-PLUGIN: FOREGROUND:\t olduser port: " << olduser->getUntrustedPort() - << "\nRADIUS-PLUGIN: FOREGROUND:\t olduser FramedIP: " << olduser->getFramedIp() - << "\nRADIUS-PLUGIN: FOREGROUND:\t newuser ip: " << newuser->getCallingStationId() - << "\nRADIUS-PLUGIN: FOREGROUND:\t newuser port: " << newuser->getUntrustedPort() - << "\n"; - //delete the newuser and use the olduser - delete newuser; - newuser=olduser; + cerr << getTime() << "RADIUS-PLUGIN: Bad config file or error in config.\n"; + goto error; } - /*can never be reached, because the key already contains the ip and the port -> else if(olduser!=NULL && (olduser->getCallingStationId().compare(newuser->getCallingStationId())!=0 || olduser->getUntrustedPort().compare(newuser->getUntrustedPort())!=0)) + + } + + + // Make a socket for foreground and background processes + // to communicate. + //Authentication process: + if ( socketpair ( PF_UNIX, SOCK_DGRAM, 0, fd_auth ) == -1 ) + { + cerr << getTime() << "RADIUS-PLUGIN: socketpair call failed for authentication process\n"; + goto error; + } + //Accounting process: + if ( socketpair ( PF_UNIX, SOCK_DGRAM, 0, fd_acct ) == -1 ) + { + cerr << getTime() << "RADIUS-PLUGIN: socketpair call failed for accounting process\n"; + goto error; + } + + + + + // Fork off the privileged processes. It will remain privileged + // even after the foreground process drops its privileges. + + + // Fork the authentication process + pid = fork (); + if ( pid ) + { + // Foreground Process (Parent) + int status; + + //save the process id + context->setAuthPid ( pid ); + + // close our copy of child's socket + close ( fd_auth[1] ); + + /* don't let future subprocesses inherit child socket */ + if ( fcntl ( fd_auth[0], F_SETFD, FD_CLOEXEC ) < 0 ) + cerr << getTime() << "RADIUS-PLUGIN: Set FD_CLOEXEC flag on socket file descriptor failed\n"; + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: Start BACKGROUND Process for authentication with PID " << context->getAuthPid() << ".\n"; + + //save the socket number in the context + context->authsocketbackgr.setSocket ( fd_auth[0] ); + + //wait for background child process to initialize */ + status = context->authsocketbackgr.recvInt(); + + if ( status != RESPONSE_INIT_SUCCEEDED ) { - if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: FOREGROUND: Error: User already authenticated with other ip or port. " - << "\nRADIUS-PLUGIN: FOREGROUND:\t olduser ip: " << olduser->getCallingStationId() - << "\nRADIUS-PLUGIN: FOREGROUND:\t olduser port: " << olduser->getUntrustedPort() - << "\nRADIUS-PLUGIN: FOREGROUND:\t newuser ip: " << newuser->getCallingStationId() - << "\nRADIUS-PLUGIN: FOREGROUND:\t newuser port: " << newuser->getUntrustedPort() - << "\n"; - return OPENVPN_PLUGIN_FUNC_ERROR; - }*/ - else //new user for authentication, no renegotiation + //set the socket to -1 if the initialization failed + context->authsocketbackgr.setSocket ( -1 ); + } + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: Start AUTH-RADIUS-PLUGIN\n"; + } + else + { + + //Background Process + + // close all parent fds except our socket back to parent + close_fds_except ( fd_auth[1] ); + + // Ignore most signals (the parent will receive them) + set_signals (); + + //save the socket number in the context + context->authsocketforegr.setSocket ( fd_auth[1] ); + + //start the backgroung event loop for accounting + Auth.Authentication ( context ); + + //close the socket + close ( fd_auth[1] ); + + //free the context of the background process + delete context; + + exit ( 0 ); + return 0; // NOTREACHED + } + + // Fork the accounting process + pid = fork (); + if ( pid ) + { + // Foreground Process (Parent) + int status; //status if the background process + + //save the pid + context->setAcctPid ( pid ); + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: Start BACKGROUND Process for accounting with PID " << context->getAcctPid() << ".\n"; + + // close our copy of child's socket */ + close ( fd_acct[1] ); + + /* don't let future subprocesses inherit child socket */ + if ( fcntl ( fd_acct[0], F_SETFD, FD_CLOEXEC ) < 0 ) + cerr << getTime() << "RADIUS-PLUGIN: Set FD_CLOEXEC flag on socket file descriptor failed\n"; + + //save the socket number in the context + context->acctsocketbackgr.setSocket ( fd_acct[0] ); + + // wait for background child process to initialize */ + status = context->acctsocketbackgr.recvInt(); + + if ( status != RESPONSE_INIT_SUCCEEDED ) { - newuser->setPortnumber(context->addNasPort()); - newuser->setSessionId(createSessionId(newuser)); + //set the socket to -1 if the initialization failed + context->acctsocketbackgr.setSocket ( -1 ); } - - - if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: FOREGROUND: New user: username: "<< newuser->getUsername() <<", password: *****" - << ", newuser ip: " << newuser->getCallingStationId() - << ", newuser port: " << newuser->getUntrustedPort() << " .\n"; + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: Start AUTH-RADIUS-PLUGIN\n"; + } + else + { + + //Background Process + + // close all parent fds except our socket back to parent + close_fds_except ( fd_acct[1] ); + + // Ignore most signals (the parent will receive them) + set_signals (); + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: Start BACKGROUND Process for accounting\n"; + + // save the socket in the context + context->acctsocketforegr.setSocket ( fd_acct[1] ); + + //start the backgroung event loop for accounting + Acct.Accounting ( context ); + + //close the socket + close ( fd_acct[1] ); + + //free the context of the background process + delete context; + exit ( 0 ); + return 0; // NOTREACHED + } + + //return the context, this is used between the functions + //openvpn_plugin_open_v1 + //openvpn_plugin_func_v1 + //openvpn_plugin_close_v1 + return ( openvpn_plugin_handle_t ) context; + + error: + //delete the context + if ( context ) + delete ( context ); + return NULL; + } + + + /** This funtion is called from the OpenVpn process everytime + * a event happens. The function handle the events (plugins) + * AUTH_USER_PASS_VERIFY, CLIENT_CONNECT, CLIENT_DISCONNECT. + * The function reads the information from the envriomental + * variable and sends the relevant information to the + * background processes. + * AUTH_USER_PASS_VERIFY: The user is authenticated by a radius server, + * if it succeeded the background sends back the framed ip, the routes and the acct_interim_interval + * for the user. Than the user is added to the context. + * CLIENT_CONNECT: The user is added to the accounting by + * sending the information to the background process. + * CLIENT_DISCONNECT: The user is deleted from the + * accounting by sending the information to the backgrund process. + * @param The handle which was allocated in the open function. + * @param The type of plugin, maybe client_conect, client_disconnect, auth_user_pass_verify + * @param A list of arguments which are set in the openvpn configuration file. + * @param The list of enviromental variables, it is created by the OpenVpn-Process. + * @return A interger with the status of the funtion (OPENVPN_PLUGIN_FUNC_SUCCESS or OPENVPN_PLUGIN_FUNC_ERROR). + */ + + //OPENVPN_EXPORT int + //openvpn_plugin_func_v1 ( openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[] ) + OPENVPN_PLUGIN_DEF int OPENVPN_PLUGIN_FUNC(openvpn_plugin_func_v2) + (openvpn_plugin_handle_t handle, + const int type, + const char *argv[], + const char *envp[], + void *per_client_context, + struct openvpn_plugin_string_list **return_list) + { - //there must be a username - if (newuser->getUsername().size() > 0) //&& olduser==NULL) + + //restore the context which was created at the function openvpn_plugin_open_v1 + PluginContext *context = ( struct PluginContext * ) handle; + + if(context->getStartThread()==true) + { + pthread_cond_init (context->getCondSend(), NULL); + pthread_mutex_init (context->getMutexSend(), NULL); + pthread_cond_init (context->getCondRecv(), NULL); + pthread_mutex_init (context->getMutexRecv(), NULL); + + if(pthread_create(context->getThread(), NULL, &auth_user_pass_verify, (void *) context) != 0) + { + cerr << getTime() << "RADIUS-PLUGIN: Thread creation failed.\n"; + return OPENVPN_PLUGIN_FUNC_ERROR; + //goto error; + } + context->setStartThread(false); + + } + + UserPlugin *newuser=NULL; /**< A context for an new user.*/ + + string common_name; /**authsocketbackgr.getSocket() ) >= 0 ) + { + + if ( DEBUG ( context->getVerbosity() ) ) + { + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY is called.\n"; + } + //create a new user + newuser=new UserPlugin(); + + + //allocate the memory, don't care about the value + try { - //send the informations to the backgorund process - context->authsocketbackgr.send(COMMAND_VERIFY); - context->authsocketbackgr.send(newuser->getUsername()); - context->authsocketbackgr.send(newuser->getPassword()); - context->authsocketbackgr.send(newuser->getPortnumber()); - context->authsocketbackgr.send(newuser->getCallingStationId()); - context->authsocketbackgr.send(newuser->getCommonname()); - context->authsocketbackgr.send(newuser->getFramedIp()); - - //get the response - const int status = context->authsocketbackgr.recvInt(); - if (status == RESPONSE_SUCCEEDED) - { - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: FOREGROUND: Authentication succeeded!\n"); - - //get the routes from background process - newuser->setFramedRoutes(context->authsocketbackgr.recvStr()); - if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: FOREGROUND: Received routes for user: "<< newuser->getFramedRoutes() << ".\n"; - //get the framed ip - newuser->setFramedIp(context->authsocketbackgr.recvStr()); - if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: FOREGROUND: Received framed ip for user: "<< newuser->getFramedIp() << ".\n"; - - - // get the interval from the background process - newuser->setAcctInterimInterval(context->authsocketbackgr.recvInt()); - if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: FOREGROUND: Receive acctinteriminterval " << newuser->getAcctInterimInterval() <<" sec from backgroundprocess.\n"; - - //clear the buffer if it isn't empty - if (newuser->getVsaBuf()!=NULL) + if ( get_env ( "username", envp ) ==NULL ) + { + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: username is not defined\n" ); + } + else if ( get_env ( "password", envp ) ==NULL ) + { + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: password is not defined\n" ); + } + else if ( get_env ( "untrusted_ip", envp ) ==NULL && get_env ( "untrusted_ip6", envp ) ==NULL ) + { + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: untrusted_ip and untrusted_ip6 is not defined\n" ); + } + else if ( get_env ( "common_name", envp ) ==NULL ) + { + if ( context->conf.getClientCertNotRequired() == false ) { - delete [] newuser->getVsaBuf(); - newuser->setVsaBuf(NULL); + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: common_name is not defined\n" ); } - // get the vendor specific attribute buffer from the background process - context->authsocketbackgr.recvBuf(newuser); - - //add the user to the context - // if the is already in the map, addUser will throw an exception - //only add the user if he it not know already - // if he has an trusted ip it is a rekeying, the user is already in the map - //if the user has a trusted ip => he is already connected it is a rekeying => don't add the user + } + else if ( get_env ( "untrusted_port", envp ) ==NULL ) + { + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: untrusted_port is not defined\n" ); + } + + if (get_env ( "auth_control_file", envp ) != NULL) + { + newuser->setAuthControlFile( get_env ( "auth_control_file", envp ) ); + } + + // get username, password, unrusted_ip and common_name from envp string array + newuser->setUsername ( get_env ( "username", envp ) ); + newuser->setPassword ( get_env ( "password", envp ) ); + + // it's ipv4 + if ( get_env ( "untrusted_ip", envp ) !=NULL ) + { + untrusted_ip = get_env ( "untrusted_ip", envp ); + } + // it's ipv6 + else + { + untrusted_ip = get_env ( "untrusted_ip6", envp ); + } + newuser->setCallingStationId ( untrusted_ip ); + //for OpenVPN option client cert not required, common_name is "UNDEF", see status.log + + if ( get_env ( "common_name", envp ) !=NULL ) + { + newuser->setCommonname ( get_env ( "common_name", envp ) ); + } - if (newuser->isAuthenticated()==false) - { - cerr << "RADIUS-PLUGIN: FOREGROUND: Add user to map.\n"; - //save the success - newuser->setAuthenticated(true); - - //add the user to the context - context->addUser(newuser); - if (olduser == NULL) delete newuser; - return OPENVPN_PLUGIN_FUNC_SUCCESS; - } - else if(newuser->isAuthenticated()==true && olduser!=NULL ) - { - cerr << "RADIUS-PLUGIN: FOREGROUND: Don't add the user to the map, it is a rekeying.\n"; - if (olduser == NULL) delete newuser; - return OPENVPN_PLUGIN_FUNC_SUCCESS; - } - + //rewrite the username if OpenVPN use the option username-as-comon-name + if ( context->conf.getUsernameAsCommonname() == true ) + { + if ( DEBUG ( context->getVerbosity() ) ) cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: Commonname set to Username\n"; + newuser->setCommonname ( get_env ( "username", envp ) ); } - else //AUTH failed - { - if(newuser->isAuthenticated()==true && olduser!=NULL) //user is already known, delete him from the accounting - { - cerr << "RADIUS-PLUGIN: FOREGROUND: Error ar rekeying!\n"; - //error on authenticate user at rekeying -> delete the user! - //send the information to the background process - context->acctsocketbackgr.send(DEL_USER); - context->acctsocketbackgr.send(newuser->getKey()); - - //get the responce - const int status = context->acctsocketbackgr.recvInt(); - if (status == RESPONSE_SUCCEEDED) - { - if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: FOREGROUND: Accouting for user with key" << newuser->getKey() << " stopped!\n"; - } - else - { - cerr << "RADIUS-PLUGIN: FOREGROUND: Error in ACCT Background Process!\n"; - cerr << "RADIUS-PLUGIN: FOREGROUND: User is deleted from the user map!\n"; - } - } - throw Exception("RADIUS-PLUGIN: FOREGROUND: Error receiving auth confirmation from background process.\n"); - } + + + newuser->setUntrustedPort ( get_env ( "untrusted_port", envp ) ); + newuser->setKey ( newuser->getCommonname() +string ( "," ) + untrusted_ip + string ( ":" ) + get_env ( "untrusted_port", envp ) ); + + if (newuser->getAuthControlFile().length() > 0) + { + + pthread_mutex_lock(context->getMutexSend()); + context->addNewUser(newuser); + pthread_cond_signal( context->getCondSend( )); + pthread_mutex_unlock (context->getMutexSend()); + return OPENVPN_PLUGIN_FUNC_DEFERRED; + } + else + { + + pthread_mutex_lock(context->getMutexSend()); + context->addNewUser(newuser); + pthread_cond_signal( context->getCondSend( )); + pthread_mutex_unlock (context->getMutexSend()); + pthread_cond_wait( context->getCondRecv(), context->getMutexRecv()); + return context->getResult(); + } + + } - } - catch(const Exception &e) - { - cerr << e; - - } - catch (...) - { - cerr << "Unknown Exception!"; - } - //remove the nas port number - context->delNasPort(newuser->getPortnumber()); - if (olduser == NULL) //the wasn't added to the context - { - delete newuser; - } - else //the user is in the context - { - context->delUser(newuser->getKey()); - } - return OPENVPN_PLUGIN_FUNC_ERROR; - } - /////////////////////////// CLIENT_CONNECT - - if (type == OPENVPN_PLUGIN_CLIENT_CONNECT && context->acctsocketbackgr.getSocket() >= 0) - { - - - if (DEBUG (context->getVerbosity())) - { - cerr << "RADIUS-PLUGIN: FOREGROUND: OPENVPN_PLUGIN_CLIENT_CONNECT is called.\n"; - } - - try{ - if (get_env ("untrusted_ip", envp)==NULL && get_env("untrusted_ip6", envp)==NULL) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: untrusted_ip and untrusted_ip6 is not defined\n"); - } - else if (get_env ("common_name", envp)==NULL) - { - if (context->conf.getClientCertNotRequired() == false) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: common_name is not defined\n"); - } - } - else if (get_env ("untrusted_port", envp)==NULL) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: untrusted_port is not defined\n"); - } - else if (get_env ("ifconfig_pool_remote_ip", envp)==NULL) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: ifconfig_pool_remote_ip is not defined\n"); - } - //get username, password and trusted_ip from envp string array - //for OpenVPN option client cert not required, common_name is "UNDEF", see status.log - - if(get_env ("untrusted_ip", envp)!=NULL) - { - untrusted_ip = get_env ("untrusted_ip", envp); + catch ( Exception &e ) + { + cerr << getTime() << e; + } + catch ( ... ) + { + cerr << getTime() << "Unknown Exception!"; + + } + return OPENVPN_PLUGIN_FUNC_ERROR; + /////////////////////////// CLIENT_CONNECT } - else + if ( type == OPENVPN_PLUGIN_CLIENT_CONNECT && context->acctsocketbackgr.getSocket() >= 0 ) { - untrusted_ip = get_env ("untrusted_ip6", envp); - } - - if (get_env ("common_name", envp)!=NULL) - { - common_name=get_env ("common_name", envp); - } - else - { - common_name="UNDEF"; - } - //rewrite the username if OpenVPN use the option username-as-comon-name - if(context->conf.getUsernameAsCommonname() == true) - { - common_name=get_env ("username", envp); - } - //get the IP assigned to the client - - const char *ifconfig_pool_remote_ip=get_env ("ifconfig_pool_remote_ip", envp); - //find the user in the context, he was added at the OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY - string key=common_name + string(",") +untrusted_ip+string(":") + string(get_env ("untrusted_port", envp)); - - newuser=context->findUser(key); - //set the assigned ip as Framed-IP-Attribute of the user (see RFC2866, chapter 4.1 for more information) - newuser->setFramedIp(string(ifconfig_pool_remote_ip)); - if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: FOREGROUND: Set FramedIP to the IP (" << newuser->getFramedIp() << ") OpenVPN assigned to the user " << newuser->getUsername() << "\n"; - //the user must be there and must be authenticated but not accounted - // isAccounted and isAuthenticated is true it is client connect for renegotiation, the user is already in the accounting process - if (newuser!=NULL && newuser->isAccounted()==false && newuser->isAuthenticated()==true) + + + if ( DEBUG ( context->getVerbosity() ) ) { - //transform the integers to strings to send them over the socket - - if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: FOREGROUND: Add user for accounting: username: " << newuser->getUsername() << ", commonname: " << newuser->getCommonname() << "\n"; - - //send information to the background process - context->acctsocketbackgr.send(ADD_USER); - context->acctsocketbackgr.send(newuser->getUsername()); - context->acctsocketbackgr.send(newuser->getSessionId()); - context->acctsocketbackgr.send(newuser->getPortnumber()); - context->acctsocketbackgr.send(newuser->getCallingStationId()); - context->acctsocketbackgr.send(newuser->getFramedIp()); - context->acctsocketbackgr.send(newuser->getCommonname()); - context->acctsocketbackgr.send(newuser->getAcctInterimInterval()); - context->acctsocketbackgr.send(newuser->getFramedRoutes()); - context->acctsocketbackgr.send(newuser->getKey()); - context->acctsocketbackgr.send(newuser->getUntrustedPort()); - context->acctsocketbackgr.send(newuser->getVsaBuf(), newuser->getVsaBufLen()); - //get the response - const int status = context->acctsocketbackgr.recvInt(); - if (status == RESPONSE_SUCCEEDED) - { - newuser->setAccounted(true); - - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: FOREGROUND: Accouting succeeded!\n"); - - return OPENVPN_PLUGIN_FUNC_SUCCESS; - } + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: OPENVPN_PLUGIN_CLIENT_CONNECT is called.\n"; + } + + try + { + if ( get_env ( "untrusted_ip", envp ) ==NULL && get_env ( "untrusted_ip6", envp ) ==NULL ) + { + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: untrusted_ip and untrusted_ip6 is not defined\n" ); + } + else if ( get_env ( "common_name", envp ) ==NULL ) + { + if ( context->conf.getClientCertNotRequired() == false ) + { + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: common_name is not defined\n" ); + } + } + else if ( get_env ( "untrusted_port", envp ) ==NULL ) + { + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: untrusted_port is not defined\n" ); + } + else if ( get_env ( "ifconfig_pool_remote_ip", envp ) ==NULL ) + { + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: ifconfig_pool_remote_ip is not defined\n" ); + } + //get username, password and trusted_ip from envp string array + //for OpenVPN option client cert not required, common_name is "UNDEF", see status.log + + if ( get_env ( "untrusted_ip", envp ) !=NULL ) + { + untrusted_ip = get_env ( "untrusted_ip", envp ); + } + else + { + untrusted_ip = get_env ( "untrusted_ip6", envp ); + } + + if ( get_env ( "common_name", envp ) !=NULL ) + { + common_name=get_env ( "common_name", envp ); + } + else + { + common_name="UNDEF"; + } + //rewrite the username if OpenVPN use the option username-as-comon-name + if ( context->conf.getUsernameAsCommonname() == true ) + { + common_name=get_env ( "username", envp ); + } + //get the IP assigned to the client + + const char *ifconfig_pool_remote_ip=get_env ( "ifconfig_pool_remote_ip", envp ); + //find the user in the context, he was added at the OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY + string key=common_name + string ( "," ) +untrusted_ip+string ( ":" ) + string ( get_env ( "untrusted_port", envp ) ); + + newuser=context->findUser(key); + if(newuser == NULL) + { + + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: User should be accounted but is unknown, should never happen.\n" ); + } + + //set the assigned ip as Framed-IP-Attribute of the user (see RFC2866, chapter 4.1 for more information) + newuser->setFramedIp ( string ( ifconfig_pool_remote_ip ) ); + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: Set FramedIP to the IP (" << newuser->getFramedIp() << ") OpenVPN assigned to the user " << newuser->getUsername() << "\n"; + //the user must be there and must be authenticated but not accounted + // isAccounted and isAuthenticated is true it is client connect for renegotiation, the user is already in the accounting process + if ( newuser!=NULL && newuser->isAccounted() ==false && newuser->isAuthenticated() ==true ) + { + //transform the integers to strings to send them over the socket + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: Add user for accounting: username: " << newuser->getUsername() << ", commonname: " << newuser->getCommonname() << "\n"; + + //send information to the background process + context->acctsocketbackgr.send ( ADD_USER ); + context->acctsocketbackgr.send ( newuser->getUsername() ); + context->acctsocketbackgr.send ( newuser->getSessionId() ); + context->acctsocketbackgr.send ( newuser->getPortnumber() ); + context->acctsocketbackgr.send ( newuser->getCallingStationId() ); + context->acctsocketbackgr.send ( newuser->getFramedIp() ); + context->acctsocketbackgr.send ( newuser->getCommonname() ); + context->acctsocketbackgr.send ( newuser->getAcctInterimInterval() ); + context->acctsocketbackgr.send ( newuser->getFramedRoutes() ); + context->acctsocketbackgr.send ( newuser->getKey() ); + context->acctsocketbackgr.send ( newuser->getUntrustedPort() ); + context->acctsocketbackgr.send ( newuser->getVsaBuf(), newuser->getVsaBufLen() ); + //get the response + const int status = context->acctsocketbackgr.recvInt(); + if ( status == RESPONSE_SUCCEEDED ) + { + newuser->setAccounted ( true ); + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: Accouting succeeded!\n"; + + return OPENVPN_PLUGIN_FUNC_SUCCESS; + } + else + { + //free the nasport + context->delNasPort ( newuser->getPortnumber() ); + string error; + error="RADIUS-PLUGIN: FOREGROUND: Accounting failed for user:"; + error+=newuser->getUsername(); + error+="!\n"; + //delete user from context + context->delUser ( newuser->getKey() ); + throw Exception ( error ); + } + } else { - //free the nasport - context->delNasPort(newuser->getPortnumber()); + string error; - error="RADIUS-PLUGIN: FOREGROUND: Accounting failed for user:"; - error+=newuser->getUsername(); + error="RADIUS-PLUGIN: FOREGROUND: No user with this commonname or he is already authenticated: "; + error+=common_name; error+="!\n"; - //delete user from context - context->delUser(newuser->getKey()); - throw Exception(error); + throw Exception ( error ); + } } - else + catch ( Exception &e ) { - - string error; - error="RADIUS-PLUGIN: FOREGROUND: No user with this commonname or he is already authenticated: "; - error+=common_name; - error+="!\n"; - throw Exception(error); - + cerr << getTime() << e; + } + catch ( ... ) + { + cerr << getTime() << "Unknown Exception!"; + } - } - catch (Exception &e) - { - cerr << e; - return OPENVPN_PLUGIN_FUNC_ERROR; - } - catch (...) - { - cerr << "Unknown Exception!"; return OPENVPN_PLUGIN_FUNC_ERROR; } - } - - ///////////////////////// OPENVPN_PLUGIN_CLIENT_DISCONNECT - - if (type == OPENVPN_PLUGIN_CLIENT_DISCONNECT && context->acctsocketbackgr.getSocket() >= 0) - { - - - if (DEBUG (context->getVerbosity())) - { - cerr << "\n\nRADIUS-PLUGIN: FOREGROUND: OPENVPN_PLUGIN_CLIENT_DISCONNECT is called.\n"; - } - try{ - if (get_env ("untrusted_ip", envp)==NULL && get_env ("untrusted_ip6", envp)==NULL) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: untrusted_ip and untrusted_ip6 is not defined\n"); - } - else if (get_env ("common_name", envp)==NULL) - { - if (context->conf.getClientCertNotRequired() == false) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: common_name is not defined\n"); - } - } - else if (get_env ("untrusted_port", envp)==NULL) - { - throw Exception( "RADIUS-PLUGIN: FOREGROUND: untrusted_port is not defined\n"); - } - - if(get_env ("untrusted_ip", envp)!=NULL) - { - untrusted_ip = get_env ("untrusted_ip", envp); - } - else + + ///////////////////////// OPENVPN_PLUGIN_CLIENT_DISCONNECT + + if ( type == OPENVPN_PLUGIN_CLIENT_DISCONNECT && context->acctsocketbackgr.getSocket() >= 0 ) { - untrusted_ip = get_env ("untrusted_ip6", envp); - } - - - - // get common_name from envp string array, if you don't use certificates it is "UNDEF" - // get username, password and trusted_ip from envp string array - //for OpenVPN option client cert not required, common_name is "UNDEF", see status.log - if (get_env ("common_name", envp)!=NULL) - { - common_name=get_env ("common_name", envp); - } - else - { - common_name="UNDEF"; - } - //rewrite the username if OpenVPN use the option username-as-comon-name - if(context->conf.getUsernameAsCommonname() == true) - { - common_name=get_env ("username", envp); - } - - //find the user in the context - newuser=context->findUser(common_name + string(",") + untrusted_ip + string(":") + string(get_env ("untrusted_port", envp))); - - - if (newuser!=NULL) + + + if ( DEBUG ( context->getVerbosity() ) ) { - - if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: FOREGROUND: Delete user for accounting: commonname: " << newuser->getKey() << "\n"; - - + cerr << getTime() << "\n\nRADIUS-PLUGIN: FOREGROUND: OPENVPN_PLUGIN_CLIENT_DISCONNECT is called.\n"; + } + try + { + if ( get_env ( "untrusted_ip", envp ) ==NULL && get_env ( "untrusted_ip6", envp ) ==NULL ) + { + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: untrusted_ip and untrusted_ip6 is not defined\n" ); + } + else if ( get_env ( "common_name", envp ) ==NULL ) + { + if ( context->conf.getClientCertNotRequired() == false ) + { + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: common_name is not defined\n" ); + } + } + else if ( get_env ( "untrusted_port", envp ) ==NULL ) + { + throw Exception ( "RADIUS-PLUGIN: FOREGROUND: untrusted_port is not defined\n" ); + } + + if ( get_env ( "untrusted_ip", envp ) !=NULL ) + { + untrusted_ip = get_env ( "untrusted_ip", envp ); + } + else + { + untrusted_ip = get_env ( "untrusted_ip6", envp ); + } + + + + // get common_name from envp string array, if you don't use certificates it is "UNDEF" + // get username, password and trusted_ip from envp string array + //for OpenVPN option client cert not required, common_name is "UNDEF", see status.log + if ( get_env ( "common_name", envp ) !=NULL ) + { + common_name=get_env ( "common_name", envp ); + } + else + { + common_name="UNDEF"; + } + //rewrite the username if OpenVPN use the option username-as-comon-name + if ( context->conf.getUsernameAsCommonname() == true ) + { + common_name=get_env ( "username", envp ); + } + + //find the user in the context + newuser=context->findUser ( common_name + string ( "," ) + untrusted_ip + string ( ":" ) + string ( get_env ( "untrusted_port", envp ) ) ); + + + if ( newuser!=NULL ) + { + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: Delete user for accounting: commonname: " << newuser->getKey() << "\n"; + + //send the information to the background process - context->acctsocketbackgr.send(DEL_USER); - context->acctsocketbackgr.send(newuser->getKey()); - + context->acctsocketbackgr.send ( DEL_USER ); + context->acctsocketbackgr.send ( newuser->getKey() ); + //get the responce - const int status = context->acctsocketbackgr.recvInt(); - if (status == RESPONSE_SUCCEEDED) - { - if (DEBUG (context->getVerbosity())) - cerr << "RADIUS-PLUGIN: FOREGROUND: Accouting for user with key" << newuser->getKey() << " stopped!\n"; - + const int status = context->acctsocketbackgr.recvInt(); + if ( status == RESPONSE_SUCCEEDED ) + { + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: Accouting for user with key" << newuser->getKey() << " stopped!\n"; + //free the nasport - context->delNasPort(newuser->getPortnumber()); - + context->delNasPort ( newuser->getPortnumber() ); + //delete user from context - context->delUser(newuser->getKey()); + context->delUser ( newuser->getKey() ); return OPENVPN_PLUGIN_FUNC_SUCCESS; - } - else - { - //free the nasport - context->delNasPort(newuser->getPortnumber()); - + } + else + { + //free the nasport + context->delNasPort ( newuser->getPortnumber() ); + //delete user from context - context->delUser(newuser->getKey()); - cerr << "RADIUS-PLUGIN: FOREGROUND: Error in ACCT Background Process!\n"; - - } - + context->delUser ( newuser->getKey() ); + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: Error in ACCT Background Process!\n"; + + } + + } + else + { + throw Exception ( "No user with this common_name!\n" ); + + } } - else + catch ( Exception &e ) { - throw Exception("No user with this common_name!\n"); - + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND:" << e; + } + catch ( ... ) + { + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND:" << "Unknown Exception!\n"; } + } - catch (Exception &e) - { - //free the nasport - cerr << "RADIUS-PLUGIN: FOREGROUND:" << e; - } - catch (...) - { - cerr << "RADIUS-PLUGIN: FOREGROUND:" << "Unknown Exception!\n"; - } - - } - - return OPENVPN_PLUGIN_FUNC_ERROR; -} + return OPENVPN_PLUGIN_FUNC_ERROR; + } -/** The function is called when the OpenVpn process exits. - * A exit command is send to the background processes and - * the context is freed which was allocted in the open function. - * @param The handle which was allocated in the open function. - */ - -OPENVPN_EXPORT void openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) -{ - //restore the context - PluginContext *context = (PluginContext *) handle; - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: FOREGROUND: close\n"); + /** The function is called when the OpenVpn process exits. + * A exit command is send to the background processes and + * the context is freed which was allocted in the open function. + * @param The handle which was allocated in the open function. + */ + + OPENVPN_PLUGIN_DEF void OPENVPN_PLUGIN_FUNC(openvpn_plugin_close_v1)(openvpn_plugin_handle_t handle) + { + //restore the context + PluginContext *context = ( PluginContext * ) handle; + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: close\n"; - - if (context->authsocketbackgr.getSocket() >= 0) - { - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: FOREGROUND: close auth background process\n"); - - //tell background process to exit - try - { - context->authsocketbackgr.send(COMMAND_EXIT); - } - catch(Exception &e) - { - cerr << e; - } - - // wait for background process to exit - if (context->getAuthPid() > 0) - waitpid (context->getAuthPid(), NULL, 0); - - } - - if (context->acctsocketbackgr.getSocket() >= 0) - { - if (DEBUG (context->getVerbosity())) - fprintf (stderr, "RADIUS-PLUGIN: FOREGROUND: close acct background process.\n"); - - //tell background process to exit - try - { - context->acctsocketbackgr.send(COMMAND_EXIT); - } - catch(Exception &e) - { - cerr << e; - } - - // wait for background process to exit - if (context->getAcctPid() > 0) - waitpid (context->getAcctPid(), NULL, 0); - - } - - //free the context - delete context; -} + if ( context->authsocketbackgr.getSocket() >= 0 ) + { + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: close auth background process\n"; + + //tell background process to exit + try + { + context->authsocketbackgr.send ( COMMAND_EXIT ); + } + catch ( Exception &e ) + { + cerr << getTime() << e; + } -} //end extern "C" + // wait for background process to exit + if ( context->getAuthPid() > 0 ) + waitpid ( context->getAuthPid(), NULL, 0 ); + + } + + if ( context->acctsocketbackgr.getSocket() >= 0 ) + { + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND: close acct background process.\n"; + + //tell background process to exit + try + { + context->acctsocketbackgr.send ( COMMAND_EXIT ); + } + catch ( Exception &e ) + { + cerr << getTime() << e; + } + + // wait for background process to exit + if ( context->getAcctPid() > 0 ) + waitpid ( context->getAcctPid(), NULL, 0 ); + + } + + //stop the thread + pthread_mutex_lock(context->getMutexSend()); + context->setStopThread(true); + pthread_cond_signal( context->getCondSend( )); + pthread_mutex_unlock (context->getMutexSend()); + //wait for the thread to exit + pthread_join(*context->getThread(),NULL); + //free the context + delete context; + + } + + +} /** Original function from the openvpn auth-pam plugin. @@ -887,45 +816,45 @@ OPENVPN_EXPORT void openvpn_plugin_close_v1 (openvpn_plugin_handle_t handle) * @param The array with the enviromental variables. * @return A poniter to the variable value or NULL, if the varaible was not found. */ -const char * get_env (const char *name, const char *envp[]) +const char * get_env ( const char *name, const char *envp[] ) { - if (envp) - { - int i; - const int namelen = strlen (name); - - for (i = 0; envp[i]; ++i) + if ( envp ) + { + int i; + const int namelen = strlen ( name ); + + for ( i = 0; envp[i]; ++i ) { //compare the enviromental names - if (!strncmp (envp[i], name, namelen)) + if ( !strncmp ( envp[i], name, namelen ) ) { //if the varibale is found const char *cp = envp[i] + namelen; - //return the value behind the = - if (*cp == '=') + //return the value behind the = + if ( *cp == '=' ) return cp + 1; - } + } } - } - return NULL; + } + return NULL; } /** Original function from the openvpn auth-pam plugin. * Return the length of a string array. - * @param Array + * @param Array * @return The length of the arry. */ -int string_array_len (const char *array[]) +int string_array_len ( const char *array[] ) { - int i = 0; - if (array) - { - while (array[i]) - ++i; - } - return i; + int i = 0; + if ( array ) + { + while ( array[i] ) + ++i; + } + return i; } /** Original function from the openvpn auth-pam plugin. @@ -939,30 +868,30 @@ int string_array_len (const char *array[]) * fds from crossing a fork(). * @param The socket number which should not be closed. */ -void close_fds_except (int keep) +void close_fds_except ( int keep ) { - int i; - closelog (); - for (i = 3; i <= 100; ++i) - { - if (i != keep) - close (i); - } + int i; + closelog (); + for ( i = 3; i <= 100; ++i ) + { + if ( i != keep ) + close ( i ); + } } /** Original function from the openvpn auth-pam plugin. * Usually we ignore signals, because our parent will * deal with them. */ -void set_signals (void) +void set_signals ( void ) { - signal (SIGTERM, SIG_DFL); + signal ( SIGTERM, SIG_DFL ); - signal (SIGINT, SIG_IGN); - signal (SIGHUP, SIG_IGN); - signal (SIGUSR1, SIG_IGN); - signal (SIGUSR2, SIG_IGN); - signal (SIGPIPE, SIG_IGN); + signal ( SIGINT, SIG_IGN ); + signal ( SIGHUP, SIG_IGN ); + signal ( SIGUSR1, SIG_IGN ); + signal ( SIGUSR2, SIG_IGN ); + signal ( SIGPIPE, SIG_IGN ); } @@ -974,7 +903,7 @@ void set_signals (void) * @param A pointer to the user for which the session ID is created. * @return A string with the hash. */ -string createSessionId(UserPlugin * user) +string createSessionId ( UserPlugin * user ) { unsigned char digest[16]; char text[33]; //The digest. @@ -982,34 +911,267 @@ string createSessionId(UserPlugin * user) int i; time_t rawtime; string strtime; - memset(digest,0,16); - //build the hash - gcry_md_open(&context, GCRY_MD_MD5, 0); - gcry_md_write(context, user->getCommonname().c_str(), user->getCommonname().length()); - gcry_md_write(context, user->getCallingStationId().c_str(), user->getCallingStationId().length()); - gcry_md_write(context, user->getUntrustedPort().c_str(), user->getUntrustedPort().length()); - time (&rawtime); - strtime=ctime(&rawtime); - gcry_md_write(context, strtime.c_str(),strtime.length()); - memcpy(digest, gcry_md_read(context, GCRY_MD_MD5), 16); - gcry_md_close(context); - - + memset ( digest,0,16 ); + //build the hash + gcry_md_open ( &context, GCRY_MD_MD5, 0 ); + gcry_md_write ( context, user->getCommonname().c_str(), user->getCommonname().length() ); + gcry_md_write ( context, user->getCallingStationId().c_str(), user->getCallingStationId().length() ); + gcry_md_write ( context, user->getUntrustedPort().c_str(), user->getUntrustedPort().length() ); + time ( &rawtime ); + strtime=ctime ( &rawtime ); + gcry_md_write ( context, strtime.c_str(),strtime.length() ); + memcpy ( digest, gcry_md_read ( context, GCRY_MD_MD5 ), 16 ); + gcry_md_close ( context ); + + unsigned int h,l; char *p=text; unsigned char *c=digest; - for (i=0; i<16; i++) + for ( i=0; i<16; i++ ) { - h = *c / 16; - l = *c % 16; - c++; - *p++ = "01234567890ABCDEF"[h]; - *p++ = "01234567890ABCDEF"[l]; - } - text[32]='\0'; - return string(text); + h = *c / 16; + l = *c % 16; + c++; + *p++ = "01234567890ABCDEF"[h]; + *p++ = "01234567890ABCDEF"[l]; + } + text[32]='\0'; + return string ( text ); } +/** The function implements the thread for authentication. If the auth_control_file is specified the thread writes the results in the + * auth_control_file, if the file is not specified the thread forward the OPENVPN_PLUGIN_FUNC_SUCCESS or OPENVPN_PLUGIN_FUNC_ERROR + * to the main process. + * @param _context The context pointer from OpenVPN. + */ + +void * auth_user_pass_verify(void * _context) +{ + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Auth_user_pass_verify thread started.\n"; + PluginContext * context = (PluginContext *) _context; + //main thread loop for authentication + while(!context->getStopThread()) + { + if(context->UserWaitingtoAuth()==false) + { + if ( DEBUG ( context->getVerbosity() ) ) cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Waiting for new user.\n"; + pthread_cond_wait(context->getCondSend(),context->getMutexSend()); + if(context->getStopThread()) + { + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Stop signal received.\n"; + break; + } + } + if ( DEBUG ( context->getVerbosity() ) ) cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: New user from OpenVPN!\n"; + //is the user already known? + UserPlugin *olduser=NULL; /**getNewUser(); + olduser=context->findUser ( newuser->getKey() ); + + if ( olduser!=NULL ) //probably key renegotiation + { + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Renegotiation: username: "<< olduser->getUsername() + << "\nRADIUS-PLUGIN: FOREGROUND THREAD:\t olduser ip: " << olduser->getCallingStationId() + << "\nRADIUS-PLUGIN: FOREGROUND THREAD:\t olduser port: " << olduser->getUntrustedPort() + << "\nRADIUS-PLUGIN: FOREGROUND THREAD:\t olduser FramedIP: " << olduser->getFramedIp() + << "\nRADIUS-PLUGIN: FOREGROUND THREAD:\t newuser ip: " << olduser->getCallingStationId() + << "\nRADIUS-PLUGIN: FOREGROUND THREAD:\t newuser port: " << olduser->getUntrustedPort() + << "\n"; + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: isAuthenticated()" << olduser->isAuthenticated(); + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: isAcct()" << olduser->isAccounted(); + //delete the newuser and use the olduser + delete newuser; + newuser=olduser; + //TODO: for threading check if the user is already accounted (He must be for renegotiation) + } + else //new user for authentication, no renegotiation + { + newuser->setPortnumber ( context->addNasPort() ); + newuser->setSessionId ( createSessionId ( newuser ) ); + //add the user to the context + context->addUser(newuser); + } + + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: New user: username: "<< newuser->getUsername() <<", password: *****" + << ", newuser ip: " << newuser->getCallingStationId() + << ", newuser port: " << newuser->getUntrustedPort() << " .\n"; + + //there must be a username + if ( newuser->getUsername().size() > 0 ) //&& olduser==NULL) + { + //send the informations to the backgorund process + context->authsocketbackgr.send ( COMMAND_VERIFY ); + context->authsocketbackgr.send ( newuser->getUsername() ); + context->authsocketbackgr.send ( newuser->getPassword() ); + context->authsocketbackgr.send ( newuser->getPortnumber() ); + context->authsocketbackgr.send ( newuser->getCallingStationId() ); + context->authsocketbackgr.send ( newuser->getCommonname() ); + context->authsocketbackgr.send ( newuser->getFramedIp() ); + + //get the response + const int status = context->authsocketbackgr.recvInt(); + if ( status == RESPONSE_SUCCEEDED ) + { + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Authentication succeeded!\n"; + + //get the routes from background process + newuser->setFramedRoutes ( context->authsocketbackgr.recvStr() ); + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Received routes for user: "<< newuser->getFramedRoutes() << ".\n"; + //get the framed ip + newuser->setFramedIp ( context->authsocketbackgr.recvStr() ); + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Received framed ip for user: "<< newuser->getFramedIp() << ".\n"; + + + // get the interval from the background process + newuser->setAcctInterimInterval ( context->authsocketbackgr.recvInt() ); + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Receive acctinteriminterval " << newuser->getAcctInterimInterval() <<" sec from backgroundprocess.\n"; + + //clear the buffer if it isn't empty + if ( newuser->getVsaBuf() !=NULL ) + { + delete [] newuser->getVsaBuf(); + newuser->setVsaBuf ( NULL ); + } + // get the vendor specific attribute buffer from the background process + context->authsocketbackgr.recvBuf ( newuser ); + + //add the user to the context + // if the is already in the map, addUser will throw an exception + // only add the user if he it not known already + + if ( newuser->isAuthenticated() ==false ) + { + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Add user to map.\n"; + //save the success + newuser->setAuthenticated ( true ); + } + else if ( newuser->isAuthenticated() ==true && olduser!=NULL ) + { + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Don't add the user to the map, it is a rekeying.\n"; + } + + if(newuser->getAuthControlFile().length()>0) + { + write_auth_control_file(context, newuser->getAuthControlFile(), '1'); + } + else + { + pthread_mutex_lock(context->getMutexRecv()); + context->setResult(OPENVPN_PLUGIN_FUNC_SUCCESS); + pthread_cond_signal( context->getCondRecv( )); + pthread_mutex_unlock (context->getMutexRecv()); + } + + } + else //AUTH failed + { + if ( newuser->isAccounted()==true) //user is already known, delete him from the accounting + { + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Error ar rekeying!\n"; + //error on authenticate user at rekeying -> delete the user! + //send the information to the background process + context->acctsocketbackgr.send ( DEL_USER ); + context->acctsocketbackgr.send ( newuser->getKey() ); + + //get the responce + const int status = context->acctsocketbackgr.recvInt(); + if ( status == RESPONSE_SUCCEEDED ) + { + if ( DEBUG ( context->getVerbosity() ) ) + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Accouting for user with key" << newuser->getKey() << " stopped!\n"; + } + else + { + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Error in ACCT Background Process!\n"; + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: User is deleted from the user map!\n"; + } + } + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Error receiving auth confirmation from background process.\n"; + //clean up: nas port, context, memory + context->delNasPort(newuser->getPortnumber()); + context->delUser(newuser->getKey()); + if(newuser->getAuthControlFile().length()>0) + { + write_auth_control_file(context, newuser->getAuthControlFile(), '0'); + } + else + { + pthread_mutex_lock(context->getMutexRecv()); + context->setResult(OPENVPN_PLUGIN_FUNC_ERROR); + pthread_cond_signal( context->getCondRecv( )); + pthread_mutex_unlock (context->getMutexRecv()); + } + delete newuser; + } + } + else + { + //clean up: nas port, context, memory + context->delNasPort(newuser->getPortnumber()); + context->delUser (newuser->getKey()); + + //return OPENVPN_PLUGIN_FUNC_ERROR; + if(newuser->getAuthControlFile().length()>0) + { + write_auth_control_file(context, newuser->getAuthControlFile(), '0'); + } + else + { + pthread_mutex_lock(context->getMutexRecv()); + context->setResult(OPENVPN_PLUGIN_FUNC_ERROR); + pthread_cond_signal( context->getCondRecv( )); + pthread_mutex_unlock (context->getMutexRecv()); + } + delete newuser; + } + } + cerr << getTime() << "RADIUS-PLUGIN: FOREGROUND THREAD: Thread finished.\n"; + pthread_exit(NULL); +} + + +/** Writes the result of the authentication to the auth control file (0: failure, 1: success). + * @param filename The auth control file. + * @param c The authentication result. + */ +void write_auth_control_file(PluginContext * context, string filename, char c) +{ + ofstream file; + file.open(filename.c_str(),ios::out); + if ( DEBUG ( context->getVerbosity() )) + cerr << getTime() << "RADIUS-PLUGIN: Write " << c << " to auth_control_file "<< filename << ".\n"; + if (file.is_open()) + { + file << c; + file.close(); + } + else + { + cerr << getTime() << "RADIUS-PLUGIN: Could not open auth_control_file "<< filename << ".\n"; + } + +} + +/** Returns the current time: + * @return The current time as a string. + */ +string getTime() +{ + time_t rawtime; + struct tm * timeinfo; + time ( &rawtime ); + timeinfo = localtime ( &rawtime ); + string t(ctime(&rawtime)); + t.replace(t.find("\n"),1," "); + return t; +} diff --git a/radiusplugin.h b/radiusplugin.h index f8fac91..c6605b5 100755 --- a/radiusplugin.h +++ b/radiusplugin.h @@ -45,6 +45,10 @@ #include #include #include +#include +#include +#include +#include #include "RadiusClass/RadiusAttribute.h" #include "RadiusClass/RadiusPacket.h" #include "RadiusClass/RadiusServer.h" @@ -97,10 +101,17 @@ struct name_value_list { struct name_value data[N_NAME_VALUE]; /**