2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Author : Maxim Mamontov <faust@stargazer.dp.ua>
22 * Realization of data access via Stargazer for RADIUS
25 * $Date: 2010/04/16 12:30:02 $
30 #include <sys/types.h>
31 #include <unistd.h> // close
40 #include "stg_client.h"
44 STG_CLIENT* stgClient = NULL;
48 //-----------------------------------------------------------------------------
50 STG_CLIENT::STG_CLIENT(const std::string & host, uint16_t port, uint16_t lp, const std::string & pass)
54 /*sock = socket(AF_INET, SOCK_DGRAM, 0);
57 std::string message = strerror(errno);
58 message = "Socket create error: '" + message + "'";
59 throw std::runtime_error(message);
62 struct hostent * he = NULL;
63 he = gethostbyname(host.c_str());
66 throw std::runtime_error("gethostbyname error");
69 outerAddr.sin_family = AF_INET;
70 outerAddr.sin_port = htons(port);
71 outerAddr.sin_addr.s_addr = *(uint32_t *)he->h_addr;
73 InitEncrypt(&ctx, password);
78 STG_CLIENT::~STG_CLIENT()
83 int STG_CLIENT::PrepareNet()
88 int STG_CLIENT::Send(const RAD_PACKET & packet)
90 /*char buf[RAD_MAX_PACKET_LEN];
92 Encrypt(&ctx, buf, (char *)&packet, sizeof(RAD_PACKET) / 8);
94 int res = sendto(sock, buf, sizeof(RAD_PACKET), 0, (struct sockaddr *)&outerAddr, sizeof(outerAddr));
97 errorStr = "Error sending data";
102 int STG_CLIENT::RecvData(RAD_PACKET * packet)
104 /*char buf[RAD_MAX_PACKET_LEN];
107 struct sockaddr_in addr;
108 socklen_t len = sizeof(struct sockaddr_in);
110 res = recvfrom(sock, buf, RAD_MAX_PACKET_LEN, 0, reinterpret_cast<struct sockaddr *>(&addr), &len);
113 errorStr = "Error receiving data";
117 Decrypt(&ctx, (char *)packet, buf, res / 8);
122 int STG_CLIENT::Request(RAD_PACKET * packet, const std::string & login, const std::string & svc, uint8_t packetType)
126 memcpy((void *)&packet->magic, (void *)RAD_ID, RAD_MAGIC_LEN);
127 packet->protoVer[0] = '0';
128 packet->protoVer[1] = '1';
129 packet->packetType = packetType;
131 strncpy((char *)packet->login, login.c_str(), RAD_LOGIN_LEN);
132 strncpy((char *)packet->service, svc.c_str(), RAD_SERVICE_LEN);
138 res = RecvData(packet);
142 if (strncmp((char *)packet->magic, RAD_ID, RAD_MAGIC_LEN))
144 errorStr = "Magic invalid. Wanted: '";
146 errorStr += "', got: '";
147 errorStr += (char *)packet->magic;
155 //-----------------------------------------------------------------------------
157 const STG_PAIRS * STG_CLIENT::Authorize(const PAIRS& pairs)
163 if (Request(&packet, login, svc, RAD_AUTZ_PACKET))
166 if (packet.packetType != RAD_ACCEPT_PACKET)
169 userPassword = (char *)packet.password;*/
172 pairs.push_back(std::make_pair("Cleartext-Password", userPassword));
174 return ToSTGPairs(pairs);
177 const STG_PAIRS * STG_CLIENT::Authenticate(const PAIRS& pairs)
183 if (Request(&packet, login, svc, RAD_AUTH_PACKET))
186 if (packet.packetType != RAD_ACCEPT_PACKET)
191 return ToSTGPairs(pairs);
194 const STG_PAIRS * STG_CLIENT::PostAuth(const PAIRS& pairs)
200 if (Request(&packet, login, svc, RAD_POST_AUTH_PACKET))
203 if (packet.packetType != RAD_ACCEPT_PACKET)
206 if (svc == "Framed-User")
207 framedIP = packet.ip;
212 pairs.push_back(std::make_pair("Framed-IP-Address", inet_ntostring(framedIP)));
214 return ToSTGPairs(pairs);
217 const STG_PAIRS * STG_CLIENT::PreAcct(const PAIRS& pairs)
221 return ToSTGPairs(pairs);
224 const STG_PAIRS * STG_CLIENT::Account(const PAIRS& pairs)
229 strncpy((char *)packet.sessid, sessid.c_str(), RAD_SESSID_LEN);
233 if (Request(&packet, login, svc, RAD_ACCT_START_PACKET))
236 else if (type == "Stop")
238 if (Request(&packet, login, svc, RAD_ACCT_STOP_PACKET))
241 else if (type == "Interim-Update")
243 if (Request(&packet, login, svc, RAD_ACCT_UPDATE_PACKET))
248 if (Request(&packet, login, svc, RAD_ACCT_OTHER_PACKET))
252 if (packet.packetType != RAD_ACCEPT_PACKET)
257 return ToSTGPairs(pairs);
260 //-----------------------------------------------------------------------------
262 std::string STG_CLIENT_ST::m_host;
263 uint16_t STG_CLIENT_ST::m_port(6666);
264 std::string STG_CLIENT_ST::m_password;
266 //-----------------------------------------------------------------------------
268 STG_CLIENT* STG_CLIENT::get()
273 void STG_CLIENT::configure(const std::string& server, uint16_t port, const std::string& password)
275 if ( stgClient != NULL )
277 stgClient = new STG_CLIENT(server, port, password);
280 //-----------------------------------------------------------------------------
282 const STG_PAIR * ToSTGPairs(const PAIRS & source)
284 STG_PAIR * pairs = new STG_PAIR[source.size() + 1];
285 for (size_t pos = 0; pos < source.size(); ++pos) {
286 bzero(pairs[pos].key, sizeof(STG_PAIR::key));
287 bzero(pairs[pos].value, sizeof(STG_PAIR::value));
288 strncpy(pairs[pos].key, source[pos].first.c_str(), sizeof(STG_PAIR::key));
289 strncpy(pairs[pos].value, source[pos].second.c_str(), sizeof(STG_PAIR::value));
292 bzero(pairs[sources.size()].key, sizeof(STG_PAIR::key));
293 bzero(pairs[sources.size()].value, sizeof(STG_PAIR::value));