mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2026-01-27 10:23:13 +00:00
1
.github/workflows/cleanup.yml
vendored
1
.github/workflows/cleanup.yml
vendored
@@ -4,7 +4,6 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- 'release/*'
|
||||
types: [ closed ]
|
||||
|
||||
defaults:
|
||||
|
||||
@@ -702,7 +702,7 @@ on its behalf and send them to the device.
|
||||
|
||||
```
|
||||
{
|
||||
"radius" : <type, can be auth, acct, das> ,
|
||||
"radius" : <type, can be auth, acct, coa> ,
|
||||
"data" : <base 64 encoded raw RADIUS payload>
|
||||
"dst" : <ip:port> as a string - optional. If this is supplied, the GW will send the data to that destination,
|
||||
if not provided, the GW will use one of the radius servers it has in its configuration. This is only
|
||||
|
||||
@@ -1129,6 +1129,8 @@ components:
|
||||
$ref: '#/components/schemas/RadiusProxyServerConfig'
|
||||
acctConfig:
|
||||
$ref: '#/components/schemas/RadiusProxyServerConfig'
|
||||
coaConfig:
|
||||
$ref: '#/components/schemas/RadiusProxyServerConfig'
|
||||
|
||||
RadiusProxyPoolList:
|
||||
type: object
|
||||
@@ -2592,6 +2594,16 @@ paths:
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- RADIUSProxy
|
||||
summary: Delete RADIUS Proxy configuration.
|
||||
operationId: deleteRadiusProxyConfig
|
||||
responses:
|
||||
204:
|
||||
$ref: '#/components/responses/Success'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/deviceDashboard:
|
||||
get:
|
||||
|
||||
64
radius_config_sample.json
Normal file
64
radius_config_sample.json
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"pools" : [
|
||||
{
|
||||
"name" : "master" ,
|
||||
"description" : "master pool",
|
||||
"authConfig" : {
|
||||
"strategy" : "weighted",
|
||||
"monitor" : false,
|
||||
"monitorMethod" : "none",
|
||||
"methodParameters" : [],
|
||||
"servers" : [ {
|
||||
"name" : "svr1",
|
||||
"ip" : "10.100.0.1",
|
||||
"port" : 1812,
|
||||
"weight" : 10
|
||||
},
|
||||
{
|
||||
"name" : "svr2",
|
||||
"ip" : "10.100.10.1",
|
||||
"port" : 1812,
|
||||
"weight" : 20
|
||||
}
|
||||
]
|
||||
},
|
||||
"acctConfig" : {
|
||||
"strategy" : "random",
|
||||
"monitor" : false,
|
||||
"monitorMethod" : "none",
|
||||
"methodParameters" : [],
|
||||
"servers" : [ {
|
||||
"name" : "svr1",
|
||||
"ip" : "10.100.0.1",
|
||||
"port" : 1813,
|
||||
"weight" : 10
|
||||
},
|
||||
{
|
||||
"name" : "svr2",
|
||||
"ip" : "10.100.10.1",
|
||||
"port" : 1813,
|
||||
"weight" : 20 }
|
||||
]
|
||||
},
|
||||
"coaConfig" : {
|
||||
"strategy" : "round_robin",
|
||||
"monitor" : false,
|
||||
"monitorMethod" : "none",
|
||||
"methodParameters" : [],
|
||||
"servers" : [ {
|
||||
"name" : "svr1",
|
||||
"ip" : "10.100.0.1",
|
||||
"port" : 3799,
|
||||
"weight" : 10
|
||||
},
|
||||
{
|
||||
"name" : "svr2",
|
||||
"ip" : "10.100.10.1",
|
||||
"port" : 3799,
|
||||
"weight" : 20
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -173,6 +173,23 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceRegistry::SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Device = Devices_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if(Device!=Devices_.end() && Device->second->WSConn_!= nullptr) {
|
||||
try {
|
||||
return Device->second->WSConn_->SendRadiusCoAData(buffer,size);
|
||||
} catch (...) {
|
||||
Logger().debug(fmt::format("Could not send data to device '{}'", SerialNumber));
|
||||
Device->second->Conn_.Address = "";
|
||||
Device->second->WSConn_ = nullptr;
|
||||
Device->second->Conn_.Connected = false;
|
||||
Device->second->Conn_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceRegistry::SetPendingUUID(uint64_t SerialNumber, uint64_t PendingUUID) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
|
||||
@@ -105,6 +105,7 @@ namespace OpenWifi {
|
||||
|
||||
bool SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
|
||||
private:
|
||||
inline static std::atomic_uint64_t Id_=1;
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace OpenWifi {
|
||||
const int RADIUS_BUFFER_SIZE = 2048;
|
||||
const int DEFAULT_RADIUS_AUTHENTICATION_PORT = 1812;
|
||||
const int DEFAULT_RADIUS_ACCOUNTING_PORT = 1813;
|
||||
const int DEFAULT_RADIUS_CoA_PORT = 3799;
|
||||
|
||||
int RADIUS_proxy_server::Start() {
|
||||
|
||||
@@ -30,35 +31,59 @@ namespace OpenWifi {
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||
AccountingSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6,true);
|
||||
|
||||
Poco::Net::SocketAddress CoASockAddrV4(Poco::Net::AddressFamily::IPv4,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
|
||||
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4,true);
|
||||
Poco::Net::SocketAddress CoASockAddrV6(Poco::Net::AddressFamily::IPv6,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
|
||||
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6,true);
|
||||
|
||||
AuthenticationReactor_.addEventHandler(*AuthenticationSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
AuthenticationReactor_.addEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
|
||||
AccountingReactor_.addEventHandler(*AccountingSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
AuthenticationReactor_.addEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
AccountingReactor_.addEventHandler(*AccountingSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
|
||||
|
||||
CoAReactor_.addEventHandler(*CoASocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||
CoAReactor_.addEventHandler(*CoASocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||
|
||||
AuthenticationReactorThread_.start(AuthenticationReactor_);
|
||||
AccountingReactorThread_.start(AccountingReactor_);
|
||||
CoAReactorThread_.start(CoAReactor_);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::Stop() {
|
||||
AuthenticationReactor_.removeEventHandler(*AuthenticationSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
AuthenticationReactor_.removeEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
|
||||
AccountingReactor_.removeEventHandler(*AccountingSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
AuthenticationReactor_.removeEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
AccountingReactor_.removeEventHandler(*AccountingSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
|
||||
CoAReactor_.removeEventHandler(*CoASocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
CoAReactor_.removeEventHandler(*CoASocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
|
||||
AuthenticationReactor_.stop();
|
||||
AuthenticationReactorThread_.join();
|
||||
|
||||
AccountingReactor_.stop();
|
||||
AccountingReactorThread_.join();
|
||||
|
||||
CoAReactor_.stop();
|
||||
CoAReactorThread_.join();
|
||||
}
|
||||
|
||||
std::string ExtractSerialNumber(const unsigned char *b, uint32_t s) {
|
||||
@@ -117,7 +142,6 @@ namespace OpenWifi {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void RADIUS_proxy_server::OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
Poco::Net::SocketAddress Sender;
|
||||
unsigned char Buffer[RADIUS_BUFFER_SIZE];
|
||||
@@ -144,6 +168,19 @@ namespace OpenWifi {
|
||||
DeviceRegistry()->SendRadiusAuthenticationData(SerialNumber,Buffer,ReceiveSize);
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::OnCoASocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
Poco::Net::SocketAddress Sender;
|
||||
unsigned char Buffer[RADIUS_BUFFER_SIZE];
|
||||
|
||||
auto ReceiveSize = pNf.get()->socket().impl()->receiveBytes(Buffer,sizeof(Buffer));
|
||||
if(ReceiveSize<SMALLEST_RADIUS_PACKET)
|
||||
return;
|
||||
auto SerialNumber = ExtractSerialNumber(&Buffer[20],ReceiveSize);
|
||||
Logger().information(fmt::format("CoA Packet received for {}",SerialNumber));
|
||||
std::cout << "Received an CoA packet for :" << SerialNumber << std::endl;
|
||||
DeviceRegistry()->SendRadiusCoAData(SerialNumber,Buffer,ReceiveSize);
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SendAccountingData(const std::string &serialNumber, const std::string &Destination,const char *buffer, std::size_t size) {
|
||||
Poco::Net::SocketAddress Dst(Destination);
|
||||
|
||||
@@ -168,6 +205,18 @@ namespace OpenWifi {
|
||||
std::cout << "Sending Authentication data to " << Destination << std::endl;
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SendCoAData(const std::string &serialNumber, const std::string &Destination,const char *buffer, std::size_t size) {
|
||||
Poco::Net::SocketAddress Dst(Destination);
|
||||
|
||||
std::lock_guard G(Mutex_);
|
||||
if(Dst.af()==Poco::Net::AddressFamily::IPv4)
|
||||
CoASocketV4_->sendTo(buffer,(int)size,Route(Dst,CoAPoolsV4_,CoAPoolsIndexV4_));
|
||||
else
|
||||
CoASocketV6_->sendTo(buffer,(int)size,Route(Dst,CoAPoolsV6_,CoAPoolsIndexV6_));
|
||||
Logger().information(fmt::format("{}: Sending CoA Packet to {}", serialNumber, Destination));
|
||||
std::cout << "Sending CoA data to " << Destination << std::endl;
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::ParseServerList(const GWObjects::RadiusProxyServerConfig & Config, PoolIndexMap_t &MapV4, PoolIndexMap_t &MapV6, PoolIndexVec_t &VecV4, PoolIndexVec_t &VecV6) {
|
||||
|
||||
std::vector<Destination> DestsV4,DestsV6;
|
||||
@@ -228,8 +277,9 @@ namespace OpenWifi {
|
||||
ResetConfig();
|
||||
PoolList_ = RPC;
|
||||
for(const auto &pool:RPC.pools) {
|
||||
ParseServerList(pool.authConfig,AuthPoolsIndexV4_, AuthPoolsIndexV6_, AuthPoolsV4_, AuthPoolsV6_);
|
||||
ParseServerList(pool.acctConfig,AcctPoolsIndexV4_, AcctPoolsIndexV6_, AcctPoolsV4_, AcctPoolsV6_);
|
||||
ParseServerList(pool.authConfig, AuthPoolsIndexV4_, AuthPoolsIndexV6_, AuthPoolsV4_, AuthPoolsV6_);
|
||||
ParseServerList(pool.acctConfig, AcctPoolsIndexV4_, AcctPoolsIndexV6_, AcctPoolsV4_, AcctPoolsV6_);
|
||||
ParseServerList(pool.coaConfig, CoAPoolsIndexV4_, CoAPoolsIndexV6_, CoAPoolsV4_, CoAPoolsV6_);
|
||||
}
|
||||
} else {
|
||||
Logger().warning(fmt::format("Configuration file '{}' is bad.",ConfigFilename_));
|
||||
@@ -331,10 +381,14 @@ namespace OpenWifi {
|
||||
AuthPoolsIndexV6_.clear();
|
||||
AcctPoolsIndexV4_.clear();
|
||||
AcctPoolsIndexV6_.clear();
|
||||
CoAPoolsIndexV4_.clear();
|
||||
CoAPoolsIndexV6_.clear();
|
||||
AuthPoolsV4_.clear();
|
||||
AuthPoolsV6_.clear();
|
||||
AcctPoolsV4_.clear();
|
||||
AcctPoolsV6_.clear();
|
||||
CoAPoolsV4_.clear();
|
||||
CoAPoolsV6_.clear();
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::DeleteConfig() {
|
||||
|
||||
@@ -22,8 +22,11 @@ namespace OpenWifi {
|
||||
|
||||
void OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
void OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
void OnCoASocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
|
||||
void SendAccountingData(const std::string &serialNumber, const std::string &Destination,const char *buffer, std::size_t size);
|
||||
void SendAuthenticationData(const std::string &serialNumber, const std::string &Destination,const char *buffer, std::size_t size);
|
||||
void SendCoAData(const std::string &serialNumber, const std::string &Destination,const char *buffer, std::size_t size);
|
||||
|
||||
void SetConfig(const GWObjects::RadiusProxyPoolList &C);
|
||||
void DeleteConfig();
|
||||
@@ -46,25 +49,38 @@ namespace OpenWifi {
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV6_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV4_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV6_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV4_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV6_;
|
||||
Poco::Net::SocketReactor AccountingReactor_;
|
||||
Poco::Net::SocketReactor AuthenticationReactor_;
|
||||
Poco::Net::SocketReactor CoAReactor_;
|
||||
Poco::Thread AuthenticationReactorThread_;
|
||||
Poco::Thread AccountingReactorThread_;
|
||||
Poco::Thread CoAReactorThread_;
|
||||
|
||||
GWObjects::RadiusProxyPoolList PoolList_;
|
||||
std::string ConfigFilename_;
|
||||
|
||||
typedef std::map<Poco::Net::SocketAddress,uint> PoolIndexMap_t;
|
||||
PoolIndexMap_t AuthPoolsIndexV4_;
|
||||
PoolIndexMap_t AcctPoolsIndexV4_;
|
||||
PoolIndexMap_t AuthPoolsIndexV6_;
|
||||
|
||||
PoolIndexMap_t AcctPoolsIndexV4_;
|
||||
PoolIndexMap_t AcctPoolsIndexV6_;
|
||||
|
||||
PoolIndexMap_t CoAPoolsIndexV4_;
|
||||
PoolIndexMap_t CoAPoolsIndexV6_;
|
||||
|
||||
typedef std::vector<std::vector<Destination>> PoolIndexVec_t;
|
||||
PoolIndexVec_t AuthPoolsV4_;
|
||||
PoolIndexVec_t AuthPoolsV6_;
|
||||
|
||||
PoolIndexVec_t AcctPoolsV4_;
|
||||
PoolIndexVec_t AcctPoolsV6_;
|
||||
|
||||
PoolIndexVec_t CoAPoolsV4_;
|
||||
PoolIndexVec_t CoAPoolsV6_;
|
||||
|
||||
RADIUS_proxy_server() noexcept:
|
||||
SubSystemServer("RADIUS-PROXY", "RADIUS-PROXY", "radius.proxy")
|
||||
{
|
||||
|
||||
@@ -314,6 +314,7 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj,"description",description);
|
||||
field_to_json(Obj,"authConfig",authConfig);
|
||||
field_to_json(Obj,"acctConfig",acctConfig);
|
||||
field_to_json(Obj,"coaConfig",coaConfig);
|
||||
}
|
||||
|
||||
bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -322,6 +323,7 @@ namespace OpenWifi::GWObjects {
|
||||
field_from_json(Obj,"description",description);
|
||||
field_from_json(Obj,"authConfig",authConfig);
|
||||
field_from_json(Obj,"acctConfig",acctConfig);
|
||||
field_from_json(Obj,"coaConfig",coaConfig);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
|
||||
@@ -237,6 +237,7 @@ namespace OpenWifi::GWObjects {
|
||||
std::string description;
|
||||
RadiusProxyServerConfig authConfig;
|
||||
RadiusProxyServerConfig acctConfig;
|
||||
RadiusProxyServerConfig coaConfig;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
|
||||
@@ -1113,6 +1113,16 @@ namespace OpenWifi {
|
||||
return Send(Payload.str());
|
||||
}
|
||||
|
||||
bool WSConnection::SendRadiusCoAData(const unsigned char * buffer, std::size_t size) {
|
||||
Poco::JSON::Object Answer;
|
||||
Answer.set(uCentralProtocol::RADIUS,uCentralProtocol::RADIUSCOA);
|
||||
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer,size));
|
||||
|
||||
std::ostringstream Payload;
|
||||
Answer.stringify(Payload);
|
||||
return Send(Payload.str());
|
||||
}
|
||||
|
||||
void WSConnection::ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc) {
|
||||
if( Doc->has(uCentralProtocol::RADIUSDATA)) {
|
||||
auto Type = Doc->get(uCentralProtocol::RADIUS).toString();
|
||||
|
||||
@@ -29,8 +29,10 @@ namespace OpenWifi {
|
||||
void ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc);
|
||||
|
||||
bool Send(const std::string &Payload);
|
||||
|
||||
bool SendRadiusAuthenticationData(const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusAccountingData(const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusCoAData(const unsigned char * buffer, std::size_t size);
|
||||
|
||||
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
|
||||
|
||||
@@ -428,6 +428,7 @@ namespace OpenWifi::uCentralProtocol {
|
||||
static const char *RADIUSDATA = "data";
|
||||
static const char *RADIUSACCT = "acct";
|
||||
static const char *RADIUSAUTH = "auth";
|
||||
static const char *RADIUSCOA = "coa";
|
||||
static const char *RADIUSDST = "dst";
|
||||
static const char *IES = "ies";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user