2 #include "radproto/attribute.h"
3 #include "radproto/packet_codes.h"
4 #include "radproto/attribute_codes.h"
7 #include "stg/common.h"
13 #include <cstdint> //uint8_t, uint32_t
17 using boost::system::error_code;
19 Server::Server(boost::asio::io_context& io_context, const std::string& secret, uint16_t port, const std::string& filePath, std::stop_token token, PluginLogger& logger, Users* users, const Config& config)
20 : m_radius(io_context, secret, port),
21 m_dictionaries(filePath),
24 m_token(std::move(token)),
41 void Server::startReceive()
43 m_radius.asyncReceive([this](const auto& error, const auto& packet, const boost::asio::ip::udp::endpoint& source){ handleReceive(error, packet, source); });
46 std::vector<RadProto::Attribute*> Server::makeAttributes(const User* user)
48 std::vector<RadProto::Attribute*> attributes;
50 for (const auto& at : m_config.getAuth().send)
52 std::string attrValue;
54 if (at.second.type == Config::AttrValue::Type::PARAM_NAME)
55 attrValue = user->GetParamValue(at.second.value);
57 attrValue = at.second.value;
59 const auto attrName = at.first;
60 const auto attrCode = m_dictionaries.attributeCode(attrName);
61 const auto attrType = m_dictionaries.attributeType(attrCode);
63 if ((attrType == "integer") && (m_dictionaries.attributeValueFindByName(attrName, attrValue)))
64 attributes.push_back(RadProto::Attribute::make(attrCode, attrType, std::to_string(m_dictionaries.attributeValueCode(attrName, attrValue))));
66 attributes.push_back(RadProto::Attribute::make(attrCode, attrType, attrValue));
71 RadProto::Packet Server::makeResponse(const RadProto::Packet& request)
73 if (request.code() != RadProto::ACCESS_REQUEST)
74 return RadProto::Packet(RadProto::ACCESS_REJECT, request.id(), request.auth(), {}, {});
78 user = findUser(request);
81 return RadProto::Packet(RadProto::ACCESS_ACCEPT, request.id(), request.auth(), makeAttributes(user), {});
83 printfd(__FILE__, "Error findUser\n");
84 return RadProto::Packet(RadProto::ACCESS_REJECT, request.id(), request.auth(), {}, {});
87 void Server::handleSend(const error_code& ec)
89 if (m_token.stop_requested())
94 m_logger("Error asyncSend: %s", ec.message().c_str());
95 printfd(__FILE__, "Error asyncSend: '%s'\n", ec.message().c_str());
100 void Server::handleReceive(const error_code& error, const std::optional<RadProto::Packet>& packet, const boost::asio::ip::udp::endpoint& source)
102 if (m_token.stop_requested())
107 m_logger("Error asyncReceive: %s", error.message().c_str());
108 printfd(__FILE__, "Error asyncReceive: '%s'\n", error.message().c_str());
112 if (packet == std::nullopt)
114 m_logger("Error asyncReceive: the request packet is missing\n");
115 printfd(__FILE__, "Error asyncReceive: the request packet is missing\n");
119 m_radius.asyncSend(makeResponse(*packet), source, [this](const auto& ec){ handleSend(ec); });
122 const User* Server::findUser(const RadProto::Packet& packet)
125 std::string password;
126 for (const auto& attribute : packet.attributes())
128 if (attribute->code() == RadProto::USER_NAME)
129 login = attribute->toString();
131 if (attribute->code() == RadProto::USER_PASSWORD)
132 password = attribute->toString();
135 User* user = nullptr;
136 if (m_users->FindByName(login, &user))
138 m_logger("User '%s' not found.", login.c_str());
139 printfd(__FILE__, "User '%s' NOT found!\n", login.c_str());
143 printfd(__FILE__, "User '%s' FOUND!\n", user->GetLogin().c_str());
145 if (password != user->GetProperties().password.Get())
147 m_logger("User's password is incorrect.");
148 printfd(__FILE__, "User's password is incorrect.\n");