buildreq.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. /*
  2. * $Id: buildreq.c,v 1.17 2010/02/04 10:27:09 aland Exp $
  3. *
  4. * Copyright (C) 1995,1997 Lars Fenneberg
  5. *
  6. * See the file COPYRIGHT for the respective terms and conditions.
  7. * If the file is missing contact me at lf@elemental.net
  8. * and I'll send you a copy.
  9. *
  10. */
  11. #include <radius_config.h>
  12. #include <includes.h>
  13. #include <freeradius-client.h>
  14. #include "util.h"
  15. /** Build a skeleton RADIUS request using information from the config file
  16. *
  17. * @param rh a handle to parsed configuration.
  18. * @param data a pointer to a #SEND_DATA structure.
  19. * @param code one of standard RADIUS codes (e.g., %PW_ACCESS_REQUEST).
  20. * @param server the name of the server.
  21. * @param port the server's port number.
  22. * @param secret the secret used by the server.
  23. * @param timeout the timeout in seconds of a message.
  24. * @param retries the number of retries.
  25. */
  26. void rc_buildreq(rc_handle const *rh, SEND_DATA *data, int code, char *server, unsigned short port,
  27. char *secret, int timeout, int retries)
  28. {
  29. data->server = server;
  30. data->secret = secret;
  31. data->svc_port = port;
  32. data->seq_nbr = rc_get_id();
  33. data->timeout = timeout;
  34. data->retries = retries;
  35. data->code = code;
  36. }
  37. /** Generates a random ID
  38. *
  39. * @return the random ID.
  40. */
  41. unsigned char rc_get_id()
  42. {
  43. return (unsigned char)(random() & UCHAR_MAX);
  44. }
  45. /** Builds an authentication/accounting request for port id client_port with the value_pairs send and submits it to a server
  46. *
  47. * @param rh a handle to parsed configuration.
  48. * @param client_port the client port number to use (may be zero to use any available).
  49. * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
  50. * @param received an allocated array of received values.
  51. * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
  52. * %PW_REPLY_MESSAGE received.
  53. * @param add_nas_port if non-zero it will include %PW_NAS_PORT in sent pairs.
  54. * @param request_type one of standard RADIUS codes (e.g., %PW_ACCESS_REQUEST).
  55. * @return received value_pairs in received, messages from the server in msg and %OK_RC (0) on success, negative
  56. * on failure as return value.
  57. */
  58. int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
  59. char *msg, int add_nas_port, int request_type)
  60. {
  61. SEND_DATA data;
  62. VALUE_PAIR *adt_vp = NULL;
  63. int result;
  64. int i, skip_count;
  65. SERVER *aaaserver;
  66. int timeout = rc_conf_int(rh, "radius_timeout");
  67. int retries = rc_conf_int(rh, "radius_retries");
  68. int radius_deadtime = rc_conf_int(rh, "radius_deadtime");
  69. double start_time = 0;
  70. double now = 0;
  71. time_t dtime;
  72. unsigned type;
  73. // -----------------------------------------------------------------------------
  74. // Мои дополнения
  75. SERVER myServer;
  76. char myServerName[NAME_LENGTH] = "192.168.14.234";
  77. char mySecret[MAX_SECRET_LENGTH] = "12345";
  78. myServer.max = 1;
  79. myServer.name[0] = myServerName;
  80. myServer.port[0] = 1645;
  81. myServer.secret[0] = mySecret;
  82. myServer.deadtime_ends[0] = 5000;
  83. aaaserver = &myServer;
  84. type = AUTH;
  85. if (aaaserver == NULL)
  86. return ERROR_RC;
  87. data.send_pairs = send;
  88. data.receive_pairs = NULL;
  89. if (add_nas_port != 0) {
  90. /*
  91. * Fill in NAS-Port
  92. */
  93. if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT,
  94. &client_port, 0, 0) == NULL)
  95. return ERROR_RC;
  96. }
  97. // -----------------------------------------------------------------------------
  98. //
  99. #if 1
  100. skip_count = 0;
  101. result = ERROR_RC;
  102. for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
  103. ; i++, now = rc_getctime())
  104. {
  105. if (aaaserver->deadtime_ends[i] != -1 &&
  106. aaaserver->deadtime_ends[i] > start_time) {
  107. skip_count++;
  108. continue;
  109. }
  110. if (data.receive_pairs != NULL) {
  111. rc_avpair_free(data.receive_pairs);
  112. data.receive_pairs = NULL;
  113. }
  114. rc_buildreq(rh, &data, request_type, aaaserver->name[i],
  115. aaaserver->port[i], aaaserver->secret[i], timeout, retries);
  116. if (request_type == PW_ACCOUNTING_REQUEST) {
  117. dtime = now - start_time;
  118. rc_avpair_assign(adt_vp, &dtime, 0);
  119. }
  120. //result = rc_send_server (rh, &data, msg, type);
  121. if (result == TIMEOUT_RC && radius_deadtime > 0)
  122. aaaserver->deadtime_ends[i] = start_time + (double)radius_deadtime;
  123. }
  124. if (result == OK_RC || result == REJECT_RC || skip_count == 0)
  125. goto exit;
  126. result = ERROR_RC;
  127. for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
  128. ; i++)
  129. {
  130. if (aaaserver->deadtime_ends[i] == -1 ||
  131. aaaserver->deadtime_ends[i] <= start_time) {
  132. continue;
  133. }
  134. if (data.receive_pairs != NULL) {
  135. rc_avpair_free(data.receive_pairs);
  136. data.receive_pairs = NULL;
  137. }
  138. rc_buildreq(rh, &data, request_type, aaaserver->name[i],
  139. aaaserver->port[i], aaaserver->secret[i], timeout, retries);
  140. if (request_type == PW_ACCOUNTING_REQUEST) {
  141. dtime = rc_getctime() - start_time;
  142. rc_avpair_assign(adt_vp, &dtime, 0);
  143. }
  144. result = rc_send_server (rh, &data, msg, type);
  145. if (result != TIMEOUT_RC)
  146. aaaserver->deadtime_ends[i] = -1;
  147. }
  148. exit:
  149. if (request_type != PW_ACCOUNTING_REQUEST) {
  150. *received = data.receive_pairs;
  151. } else {
  152. rc_avpair_free(data.receive_pairs);
  153. }
  154. #endif
  155. return result;
  156. #if 0
  157. SEND_DATA data;
  158. VALUE_PAIR *adt_vp = NULL;
  159. int result;
  160. int i, skip_count;
  161. SERVER *aaaserver;
  162. int timeout = rc_conf_int(rh, "radius_timeout");
  163. int retries = rc_conf_int(rh, "radius_retries");
  164. int radius_deadtime = rc_conf_int(rh, "radius_deadtime");
  165. double start_time = 0;
  166. double now = 0;
  167. time_t dtime;
  168. unsigned type;
  169. if (request_type != PW_ACCOUNTING_REQUEST) {
  170. aaaserver = rc_conf_srv(rh, "authserver");
  171. type = AUTH;
  172. } else {
  173. aaaserver = rc_conf_srv(rh, "acctserver");
  174. type = ACCT;
  175. }
  176. if (aaaserver == NULL)
  177. return ERROR_RC;
  178. data.send_pairs = send;
  179. data.receive_pairs = NULL;
  180. if (add_nas_port != 0) {
  181. /*
  182. * Fill in NAS-Port
  183. */
  184. if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT,
  185. &client_port, 0, 0) == NULL)
  186. return ERROR_RC;
  187. }
  188. if (request_type == PW_ACCOUNTING_REQUEST) {
  189. /*
  190. * Fill in Acct-Delay-Time
  191. */
  192. dtime = 0;
  193. now = rc_getctime();
  194. adt_vp = rc_avpair_get(data.send_pairs, PW_ACCT_DELAY_TIME, 0);
  195. if (adt_vp == NULL) {
  196. adt_vp = rc_avpair_add(rh, &(data.send_pairs),
  197. PW_ACCT_DELAY_TIME, &dtime, 0, 0);
  198. if (adt_vp == NULL)
  199. return ERROR_RC;
  200. start_time = now;
  201. } else {
  202. start_time = now - adt_vp->lvalue;
  203. }
  204. }
  205. skip_count = 0;
  206. result = ERROR_RC;
  207. for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
  208. ; i++, now = rc_getctime())
  209. {
  210. if (aaaserver->deadtime_ends[i] != -1 &&
  211. aaaserver->deadtime_ends[i] > start_time) {
  212. skip_count++;
  213. continue;
  214. }
  215. if (data.receive_pairs != NULL) {
  216. rc_avpair_free(data.receive_pairs);
  217. data.receive_pairs = NULL;
  218. }
  219. rc_buildreq(rh, &data, request_type, aaaserver->name[i],
  220. aaaserver->port[i], aaaserver->secret[i], timeout, retries);
  221. if (request_type == PW_ACCOUNTING_REQUEST) {
  222. dtime = now - start_time;
  223. rc_avpair_assign(adt_vp, &dtime, 0);
  224. }
  225. //result = rc_send_server (rh, &data, msg, type);
  226. if (result == TIMEOUT_RC && radius_deadtime > 0)
  227. aaaserver->deadtime_ends[i] = start_time + (double)radius_deadtime;
  228. }
  229. if (result == OK_RC || result == REJECT_RC || skip_count == 0)
  230. goto exit;
  231. result = ERROR_RC;
  232. for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
  233. ; i++)
  234. {
  235. if (aaaserver->deadtime_ends[i] == -1 ||
  236. aaaserver->deadtime_ends[i] <= start_time) {
  237. continue;
  238. }
  239. if (data.receive_pairs != NULL) {
  240. rc_avpair_free(data.receive_pairs);
  241. data.receive_pairs = NULL;
  242. }
  243. rc_buildreq(rh, &data, request_type, aaaserver->name[i],
  244. aaaserver->port[i], aaaserver->secret[i], timeout, retries);
  245. if (request_type == PW_ACCOUNTING_REQUEST) {
  246. dtime = rc_getctime() - start_time;
  247. rc_avpair_assign(adt_vp, &dtime, 0);
  248. }
  249. //result = rc_send_server (rh, &data, msg, type);
  250. if (result != TIMEOUT_RC)
  251. aaaserver->deadtime_ends[i] = -1;
  252. }
  253. exit:
  254. if (request_type != PW_ACCOUNTING_REQUEST) {
  255. *received = data.receive_pairs;
  256. } else {
  257. rc_avpair_free(data.receive_pairs);
  258. }
  259. return result;
  260. #endif
  261. }
  262. /** Builds an authentication request for port id client_port with the value_pairs send and submits it to a server
  263. *
  264. * @param rh a handle to parsed configuration.
  265. * @param client_port the client port number to use (may be zero to use any available).
  266. * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
  267. * @param received an allocated array of received values.
  268. * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
  269. * %PW_REPLY_MESSAGE received.
  270. * @return received value_pairs in @received, messages from the server in msg (if non-NULL),
  271. * and %OK_RC (0) on success, negative on failure as return value.
  272. */
  273. int rc_auth(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
  274. char *msg)
  275. {
  276. //return rc_aaa(rh, client_port, send, received, msg, 1, PW_ACCESS_REQUEST);
  277. return rc_aaa(rh, client_port, send, received, msg, 0, PW_ACCESS_REQUEST);
  278. }
  279. /** Builds an authentication request for proxying
  280. *
  281. * Builds an authentication request with the value_pairs send and submits it to a server.
  282. * Works for a proxy; does not add IP address, and does does not rely on config file.
  283. *
  284. * @param rh a handle to parsed configuration.
  285. * @param client_port the client port number to use (may be zero to use any available).
  286. * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
  287. * @param received an allocated array of received values.
  288. * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of
  289. * any %PW_REPLY_MESSAGE received.
  290. * @return received value_pairs in @received, messages from the server in msg (if non-NULL)
  291. * and %OK_RC (0) on success, negative on failure as return value.
  292. */
  293. int rc_auth_proxy(rc_handle *rh, VALUE_PAIR *send, VALUE_PAIR **received, char *msg)
  294. {
  295. return rc_aaa(rh, 0, send, received, msg, 0, PW_ACCESS_REQUEST);
  296. }
  297. /** Builds an accounting request for port id client_port with the value_pairs at send
  298. *
  299. * @note NAS-IP-Address, NAS-Port and Acct-Delay-Time get filled in by this function, the rest has to be supplied.
  300. *
  301. * @param rh a handle to parsed configuration.
  302. * @param client_port the client port number to use (may be zero to use any available).
  303. * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
  304. * @return received value_pairs in @received, and %OK_RC (0) on success, negative on failure as return value.
  305. */
  306. int rc_acct(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send)
  307. {
  308. return rc_aaa(rh, client_port, send, NULL, NULL, 1, PW_ACCOUNTING_REQUEST);
  309. }
  310. /** Builds an accounting request with the value_pairs at send
  311. *
  312. * @param rh a handle to parsed configuration.
  313. * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
  314. * @return %OK_RC (0) on success, negative on failure as return value.
  315. */
  316. int rc_acct_proxy(rc_handle *rh, VALUE_PAIR *send)
  317. {
  318. return rc_aaa(rh, 0, send, NULL, NULL, 0, PW_ACCOUNTING_REQUEST);
  319. }
  320. /** Asks the server hostname on the specified port for a status message
  321. *
  322. * @param rh a handle to parsed configuration.
  323. * @param host the name of the server.
  324. * @param secret the secret used by the server.
  325. * @param port the server's port number.
  326. * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
  327. * %PW_REPLY_MESSAGE received.
  328. * @return %OK_RC (0) on success, negative on failure as return value.
  329. */
  330. int rc_check(rc_handle *rh, char *host, char *secret, unsigned short port, char *msg)
  331. {
  332. SEND_DATA data;
  333. int result;
  334. uint32_t service_type;
  335. int timeout = rc_conf_int(rh, "radius_timeout");
  336. int retries = rc_conf_int(rh, "radius_retries");
  337. data.send_pairs = data.receive_pairs = NULL;
  338. /*
  339. * Fill in Service-Type
  340. */
  341. service_type = PW_ADMINISTRATIVE;
  342. rc_avpair_add(rh, &(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, 0);
  343. rc_buildreq(rh, &data, PW_STATUS_SERVER, host, port, secret, timeout, retries);
  344. //result = rc_send_server (rh, &data, msg, ACCT);
  345. rc_avpair_free(data.receive_pairs);
  346. return result;
  347. }