Эх сурвалжийг харах

Merge remote-tracking branch 'origin/radius'

balbekova 7 жил өмнө
parent
commit
f56043945c
44 өөрчлөгдсөн 5971 нэмэгдсэн , 452 устгасан
  1. 20 7
      modules/Ethernet/private_mib.c
  2. BIN
      modules/HTTP_Server/fs/rslogin.html
  3. BIN
      modules/HTTP_Server/fs/settings.html
  4. 212 131
      modules/HTTP_Server/fsdata.c
  5. 281 302
      modules/HTTP_Server/http_server.c
  6. 3 3
      modules/HTTP_Server/web_params_api.c
  7. 10 0
      modules/Makefile
  8. 1 1
      modules/common/hal.c
  9. 2 0
      modules/log/log.c
  10. 2 0
      modules/log/log.h
  11. 326 0
      modules/radius/radius_user.c
  12. 59 0
      modules/radius/radius_user.h
  13. 3 2
      modules/settings_api.c
  14. 12 0
      peripheral_modules/src/usart.c
  15. 53 0
      projects/iar/bt-670x.ewp
  16. 564 0
      thirdparty/FreeRadius/include/freeradius-client.h
  17. 189 0
      thirdparty/FreeRadius/include/includes.h
  18. 53 0
      thirdparty/FreeRadius/include/messages.h
  19. 28 0
      thirdparty/FreeRadius/include/pathnames.h
  20. 893 0
      thirdparty/FreeRadius/lib/avpair.c
  21. 178 0
      thirdparty/FreeRadius/lib/buildreq.c
  22. 943 0
      thirdparty/FreeRadius/lib/config.c
  23. 504 0
      thirdparty/FreeRadius/lib/dict.c
  24. 49 0
      thirdparty/FreeRadius/lib/fr_log.c
  25. 251 0
      thirdparty/FreeRadius/lib/fr_md5.c
  26. 86 0
      thirdparty/FreeRadius/lib/fr_md5.h
  27. 56 0
      thirdparty/FreeRadius/lib/fr_options.h
  28. 29 0
      thirdparty/FreeRadius/lib/rc-md5.c
  29. 28 0
      thirdparty/FreeRadius/lib/rc-md5.h
  30. 549 0
      thirdparty/FreeRadius/lib/sendserver.c
  31. 389 0
      thirdparty/FreeRadius/lib/util.c
  32. 50 0
      thirdparty/FreeRadius/lib/util.h
  33. 103 0
      thirdparty/FreeRadius/radius_config.h
  34. 3 0
      user/init_task.c
  35. 4 4
      user/main.h
  36. 1 0
      web_interface/Gruntfile.js
  37. BIN
      web_interface/error.html
  38. BIN
      web_interface/index.html
  39. BIN
      web_interface/login.html
  40. 35 0
      web_interface/src/wui/rslogin.html
  41. 2 2
      web_interface/src/wui/settings.html
  42. BIN
      web_interface/success.html
  43. BIN
      web_interface/upload.css
  44. BIN
      web_interface/upload.js

+ 20 - 7
modules/Ethernet/private_mib.c

@@ -481,8 +481,10 @@ static void signals_set_value (struct obj_def *od, u16_t len, void *value)
   char *val_string;
   char str[20];
   int8_t res = 0;
+  char log_string[50];
 
   memset(str, 0, 20);
+  memset(log_string, 0,50);
   
   id = od->id_inst_ptr[0];
   
@@ -528,26 +530,34 @@ static void signals_set_value (struct obj_def *od, u16_t len, void *value)
 	  if(val == 0){
 		  res = ups_metac_service_pdu(ups_cancel_test);
 		  if(res == 1){
-			  log_event_data(LOG_TEST_UPS, "Администратор(Останов)");
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Останов)");
+			  log_event_data(LOG_TEST_UPS, log_string);
 		  }
 	  }
 	  else if(val > 0 && val < 100){
 		  TimeParam = val;
 		  res = ups_metac_service_pdu(ups_test_time);
 		  if(res == 1){
-			  log_event_data(LOG_TEST_UPS, "Администратор (Запущен)");
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Запущен)");
+			  log_event_data(LOG_TEST_UPS, log_string);
 		  }
 	  }
 	  else if(val == 100){
 		  res = ups_metac_service_pdu(ups_test_10sec);
 		  if(res == 1){
-			  log_event_data(LOG_TEST_UPS, "Администратор (Запущен)");
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Запущен)");
+			  log_event_data(LOG_TEST_UPS, log_string);
 		  }
 	  }
 	  else if(val == 999){
 		  res = ups_metac_service_pdu(ups_test_low_bat);
 		  if(res == 1){
-			  log_event_data(LOG_TEST_UPS, "Администратор (Запущен)");
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Запущен)");
+			  log_event_data(LOG_TEST_UPS, log_string);
 		  }
 	  }
 	  break;
@@ -556,14 +566,17 @@ static void signals_set_value (struct obj_def *od, u16_t len, void *value)
 	  float shtdn_val = atof(val_string);
 	  if(shtdn_val == 0){
 		  res = ups_metac_service_pdu(ups_cancel_shut_down);
-		 	if(res == 1)
-		 		log_event_data(LOG_SHUTDOWN_UPS, "Администратор(Останов)");
+		 	if(res == 1){
+		 		strcpy(log_string, name_login);
+		 		strcat(log_string, " (Останов)");
+		 		log_event_data(LOG_SHUTDOWN_UPS, log_string);
+		 	}
 	  }
 	  else{
 		TimeParamFloat = shtdn_val;
 		res = ups_metac_service_pdu(ups_shutdown);
 		if(res == 1)
-			log_event_data(LOG_SHUTDOWN_UPS, "Администратор");
+			log_event_data(LOG_SHUTDOWN_UPS, name_login);
 	  }
 	  break;
     default :

BIN
modules/HTTP_Server/fs/rslogin.html


BIN
modules/HTTP_Server/fs/settings.html


+ 212 - 131
modules/HTTP_Server/fsdata.c

@@ -2465,7 +2465,79 @@ Cache-Control: private, max-age=86400
 0x98,0xf3,0x3f,0x7f,0x63,0xcb,0xae,0xe6,0x24,0xed,0x24,0x00,0x00,0x00,0x00,0x49,
 0x45,0x4e,0x44,0xae,0x42,0x60,0x82,};
 
-static const unsigned int dummy_align__settings_html = 9;
+static const unsigned int dummy_align__rslogin_html = 9;
+static const unsigned char data__rslogin_html[] = {
+/* /rslogin.html (14 chars) */
+0x2f,0x72,0x73,0x6c,0x6f,0x67,0x69,0x6e,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00,
+
+/* HTTP header */
+/* "HTTP/1.1 200 OK
+" (17 bytes) */
+0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x31,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d,
+0x0a,
+/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip)
+" (63 bytes) */
+0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33,
+0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,
+0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,
+0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
+/* "Content-Length: 593
+" (18+ bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
+0x35,0x39,0x33,0x0d,0x0a,
+/* "Connection: Close
+" (19 bytes) */
+0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x43,0x6c,0x6f,0x73,
+0x65,0x0d,0x0a,
+/* "Content-type: text/html
+Content-Encoding: gzip
+
+" (51 bytes) */
+0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65,
+0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,
+0x2d,0x45,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,0x70,0x0d,
+0x0a,0x0d,0x0a,
+/* raw file data (593 bytes) */
+0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x0a,0x7d,0x54,0xc1,0x6e,0xd4,0x30,
+0x10,0xfd,0x15,0x63,0x24,0x4e,0x75,0xb7,0x7b,0x41,0xa8,0xc4,0x91,0x50,0xe9,0x81,
+0x13,0x08,0x81,0x04,0xc7,0x49,0x32,0xbb,0x71,0x71,0x6c,0x63,0x3b,0xd9,0xdd,0x5b,
+0xc5,0x81,0x13,0x12,0x88,0x2b,0x48,0xfc,0x02,0xa2,0x07,0x8a,0x10,0xfd,0x86,0xec,
+0x1f,0x31,0x4e,0xb6,0xdb,0x46,0x48,0x1c,0xe2,0xf5,0xd8,0x33,0xe3,0x37,0xef,0x3d,
+0x6d,0x76,0xe7,0xf1,0xd3,0x93,0x17,0xaf,0x9f,0x9d,0xb2,0x3a,0x36,0x3a,0xcf,0xd2,
+0xca,0x34,0x98,0xa5,0xe4,0x9c,0x22,0x84,0x2a,0xcf,0x1a,0x8c,0xc0,0xca,0x1a,0x7c,
+0xc0,0x28,0x79,0x1b,0x17,0xe2,0x01,0xdd,0x0d,0xa7,0x75,0x8c,0x4e,0xe0,0xdb,0x56,
+0x75,0x92,0xbf,0x12,0x2f,0x1f,0x89,0x13,0xdb,0x38,0x88,0xaa,0xd0,0xc8,0x59,0x69,
+0x4d,0x44,0x43,0x25,0x4f,0x4e,0x25,0x56,0x4b,0xbc,0x2e,0x32,0xd0,0xa0,0xe4,0x9d,
+0xc2,0x95,0xb3,0x3e,0xde,0xca,0x5b,0xa9,0x2a,0xd6,0xb2,0xc2,0x4e,0x95,0x28,0x86,
+0xe0,0x40,0x19,0x15,0x15,0x68,0x11,0x4a,0xd0,0x28,0xe7,0x07,0x0d,0xac,0x55,0xd3,
+0x36,0xfb,0xb8,0x0d,0xe8,0x87,0x00,0xe8,0x49,0x79,0x44,0x4f,0x44,0x15,0x35,0xe6,
+0xfd,0xd7,0xfe,0xaa,0xff,0xd3,0x5f,0x6e,0xdf,0xf5,0x57,0xdb,0xf3,0xfe,0x92,0xf6,
+0x17,0xd9,0x6c,0xbc,0xcb,0xb4,0x32,0x6f,0x58,0xed,0x71,0x21,0x79,0x03,0xca,0x1c,
+0x96,0x21,0x70,0xe6,0x51,0x4b,0x1e,0xe2,0x46,0x63,0xa8,0x11,0x23,0x75,0x0a,0xa5,
+0x57,0x2e,0xb2,0xb8,0x71,0x04,0x37,0xe2,0x3a,0xce,0xce,0xa0,0x83,0xf1,0x94,0xb3,
+0xe0,0x4b,0xc9,0xbd,0xd5,0x78,0x78,0x16,0x28,0x79,0x36,0x9e,0xd3,0x66,0x24,0xad,
+0xb0,0xd5,0x26,0xcf,0x2a,0xd5,0xb1,0x52,0x43,0x08,0x92,0x1b,0xe8,0x0a,0xf0,0x6c,
+0xfc,0x11,0x15,0x2e,0xa0,0xd5,0xf1,0x3a,0x5c,0xa8,0x35,0x56,0x22,0x5a,0x47,0x9d,
+0xfe,0xa9,0x11,0xa9,0x23,0xfa,0xf1,0x2a,0xcf,0x60,0x07,0xfd,0x2e,0x31,0x37,0xb6,
+0xd6,0x76,0x69,0x13,0x04,0xa0,0x8f,0xaa,0xa7,0xeb,0xad,0x76,0x2b,0x0f,0xce,0x51,
+0x23,0xa6,0x2a,0xc9,0x77,0xea,0x50,0x5d,0x3d,0xcf,0x9f,0x43,0xa5,0xda,0xc0,0xfa,
+0x4f,0xfd,0x8f,0x3d,0x63,0x3f,0xfb,0xef,0xdb,0xf7,0xc4,0xe0,0x47,0x1a,0x69,0x3e,
+0x81,0xe5,0xc0,0xa0,0x66,0xc3,0x7a,0x3d,0xc8,0x14,0xf7,0x78,0x95,0x28,0xa0,0xf3,
+0x85,0xf5,0x0d,0x83,0x32,0x2a,0x6b,0x24,0x27,0xa8,0x89,0xf0,0xa5,0xe2,0x8c,0x0c,
+0x54,0x5b,0x02,0xe2,0x6c,0x48,0x26,0xd8,0x8f,0xa2,0x8c,0x48,0x25,0x54,0xa9,0xa1,
+0xa0,0x77,0x28,0xd8,0xd5,0xf1,0xbc,0xff,0x42,0xb2,0x5e,0x24,0x39,0x8f,0xef,0x99,
+0x22,0xb8,0x87,0xd9,0x6c,0x48,0xca,0x33,0x65,0x5c,0x7b,0x5b,0xab,0x7d,0xc7,0xd4,
+0x4b,0xa4,0x61,0x49,0x2b,0x4e,0x7c,0x27,0xef,0x0d,0x28,0x46,0x1a,0x76,0x5b,0xf2,
+0x95,0x46,0xb3,0x24,0xfb,0xf1,0xf9,0x7d,0x12,0x37,0xf9,0x20,0xb9,0xc3,0x13,0x5c,
+0xe1,0xd5,0xb2,0x8e,0xc7,0x6c,0x7e,0xe4,0xd6,0x53,0x54,0x8e,0x94,0x25,0x50,0xdf,
+0x88,0xa9,0x73,0x02,0xf6,0x7b,0xfb,0xe1,0x7f,0xb0,0x52,0xf6,0xca,0xfa,0xea,0xbf,
+0xd0,0x6e,0x92,0x92,0x48,0xc3,0x03,0x6c,0x0a,0x2e,0x67,0x93,0x61,0x43,0x5b,0x34,
+0xea,0x86,0xc0,0x22,0x1a,0x46,0x9f,0x70,0x5e,0x11,0xfa,0x0d,0x67,0x1d,0xe8,0x96,
+0x46,0xe9,0x3f,0x13,0xc0,0x5f,0x24,0xee,0x25,0x8d,0x30,0x4b,0xa4,0x4c,0x6d,0xb2,
+0x33,0xce,0x68,0xdb,0xd9,0xf0,0x67,0xf0,0x17,0xf4,0xb0,0xf3,0xe0,0x1c,0x04,0x00,
+0x00,};
+
+static const unsigned int dummy_align__settings_html = 10;
 static const unsigned char data__settings_html[] = {
 /* /settings.html (15 chars) */
 0x2f,0x73,0x65,0x74,0x74,0x69,0x6e,0x67,0x73,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,
@@ -2481,10 +2553,10 @@ static const unsigned char data__settings_html[] = {
 0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,
 0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,
 0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a,
-/* "Content-Length: 4534
+/* "Content-Length: 4548
 " (18+ bytes) */
 0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x4c,0x65,0x6e,0x67,0x74,0x68,0x3a,0x20,
-0x34,0x35,0x33,0x34,0x0d,0x0a,
+0x34,0x35,0x34,0x38,0x0d,0x0a,
 /* "Connection: Close
 " (19 bytes) */
 0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x43,0x6c,0x6f,0x73,
@@ -2497,7 +2569,7 @@ Content-Encoding: gzip
 0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,
 0x2d,0x45,0x6e,0x63,0x6f,0x64,0x69,0x6e,0x67,0x3a,0x20,0x67,0x7a,0x69,0x70,0x0d,
 0x0a,0x0d,0x0a,
-/* raw file data (4534 bytes) */
+/* raw file data (4548 bytes) */
 0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x0a,0xdd,0x5b,0x6b,0x73,0x1b,0xd5,
 0x19,0xfe,0x2b,0xcb,0x86,0x32,0xf2,0xd8,0x92,0x2d,0x5f,0x20,0x38,0x96,0x3a,0x34,
 0x49,0x99,0xcc,0x14,0xf0,0x10,0x53,0xe0,0x93,0x67,0x2d,0xad,0xad,0x25,0xd2,0xae,
@@ -2658,132 +2730,133 @@ Content-Encoding: gzip
 0xe1,0x98,0x51,0x24,0xd0,0x13,0xce,0x32,0xe2,0x51,0x62,0xe9,0x64,0xe4,0x04,0xa5,
 0x02,0x92,0xa9,0x3a,0x8d,0x2c,0xa3,0xb1,0x1d,0xd7,0x90,0x63,0x61,0x18,0xc4,0xa0,
 0x97,0xd2,0x64,0x29,0xfe,0xc1,0x41,0x1f,0xb0,0xe2,0xab,0x09,0x2c,0x00,0x52,0xdc,
-0x80,0x33,0x9a,0xb4,0x67,0xec,0x31,0x55,0x4b,0xd9,0x91,0x71,0x13,0x6b,0x20,0x5c,
-0x40,0x7d,0x5c,0x48,0x05,0x41,0x82,0x94,0x77,0x31,0xd2,0x03,0xdc,0xff,0x01,0x7a,
-0x3a,0x6a,0x3b,0xc9,0x21,0x2b,0x6a,0xb0,0x63,0xf5,0xc2,0x96,0x52,0xd2,0xf8,0x3a,
-0x55,0x50,0xbe,0x2b,0x56,0xcf,0x24,0xe1,0x84,0x9a,0xed,0x25,0x2b,0x59,0x1f,0x26,
-0x54,0xce,0x5a,0xd0,0xec,0x75,0x6c,0x4d,0x65,0x6d,0x2b,0x16,0xb1,0x89,0xb2,0x8b,
-0xbf,0x0e,0xc5,0xd8,0x0c,0x65,0xb9,0xba,0x67,0x44,0x7b,0x06,0x96,0xd5,0x18,0xe8,
-0xab,0xb5,0x75,0x84,0xfb,0x87,0x65,0x49,0x33,0x9a,0xdc,0x0b,0x1b,0x63,0x94,0xe2,
-0x9f,0x92,0xcd,0x71,0x5f,0x0a,0x76,0x2b,0x89,0x89,0x47,0x42,0x82,0xe5,0xc0,0x49,
-0x94,0x5a,0xd7,0x1c,0xb5,0xc2,0xe5,0xea,0x8b,0x3a,0xc1,0x94,0xb1,0xa9,0x1b,0xbc,
-0x18,0xac,0x39,0x96,0xab,0xf3,0x15,0xd4,0x1d,0x4b,0xcf,0xbf,0xb0,0x66,0xe0,0x7a,
-0x79,0x6e,0x6e,0xca,0x88,0xbe,0x93,0xca,0x1b,0x57,0xd5,0x58,0x15,0xb8,0x33,0x63,
-0x40,0xa0,0x90,0xb1,0x83,0x66,0x3f,0xe2,0xaf,0x2e,0xfc,0xa5,0x15,0xaa,0x7c,0x61,
-0xb2,0x5c,0xad,0x66,0x7a,0xac,0xaa,0x1e,0x25,0xc9,0x01,0x95,0x31,0x47,0x03,0xc9,
-0xeb,0x1e,0x6a,0x0f,0x97,0xfa,0x7f,0x8c,0x6e,0xa3,0xeb,0xeb,0xe8,0xf2,0x1e,0x5e,
-0x20,0xca,0x1b,0x5d,0x57,0x2b,0x57,0xe7,0x32,0x1d,0xce,0xa9,0x0e,0x3f,0x41,0x2b,
-0x42,0xba,0xcd,0xfc,0xac,0xa0,0xdd,0xb3,0x69,0xb3,0x67,0x55,0xab,0x2b,0x92,0xea,
-0x49,0xe2,0x5c,0xd8,0xea,0x68,0xda,0xea,0xa8,0x6a,0xf5,0x2d,0xa2,0x28,0xee,0x65,
-0x02,0x29,0x20,0x26,0xc8,0xd4,0x98,0x26,0xe1,0x0e,0xeb,0xbd,0x5a,0x72,0x50,0x21,
-0x2c,0x61,0x22,0xff,0x8a,0xae,0x88,0x3c,0x7d,0xc1,0x8f,0xf0,0x83,0x8c,0x21,0x89,
-0x28,0x40,0xf7,0x4c,0x3a,0xce,0x33,0xf1,0x9c,0x24,0x05,0x7d,0xe4,0x9e,0x9f,0x4e,
-0x7b,0x7e,0x5a,0xf5,0xfc,0x0f,0xc6,0x82,0xdc,0xba,0x00,0x50,0xdc,0x04,0xa5,0x8a,
-0xdd,0x13,0xa0,0x07,0x7f,0xbe,0x84,0x18,0x70,0x65,0x1c,0x33,0x2e,0x9c,0xcb,0x52,
-0x3a,0xe2,0x92,0x1a,0xf1,0x6a,0x52,0x47,0x67,0x19,0x77,0x42,0x5a,0x61,0xb4,0x8f,
-0xf1,0xed,0x0d,0x89,0x62,0x77,0x71,0xf7,0x17,0x8c,0x8b,0xa2,0x54,0xe1,0xb8,0x8b,
-0xe9,0xb8,0x8b,0x6a,0xdc,0x2b,0x10,0xd9,0xbb,0xc2,0xa3,0x6c,0x09,0x77,0x68,0xfc,
-0x2c,0x87,0x30,0x0e,0x6e,0x85,0x36,0xc8,0x35,0xfa,0x17,0x64,0xdc,0xdd,0xb2,0xb8,
-0x2a,0x28,0x61,0x01,0xfb,0x16,0x2a,0x70,0x80,0x4a,0x6d,0x16,0x96,0x17,0xa8,0x35,
-0x5f,0xf5,0x2f,0x23,0xec,0x7e,0x07,0x5d,0xc8,0x16,0x3b,0x9d,0x62,0xdc,0x1c,0xd3,
-0x43,0xa2,0x78,0x0b,0x0a,0xfc,0xc7,0x02,0xe2,0x27,0x4c,0xfa,0x2e,0x03,0x77,0x92,
-0x43,0xd4,0x04,0x04,0xec,0x5f,0x28,0x63,0xfd,0xff,0x36,0x3e,0x40,0x69,0x00,0x2f,
-0x3e,0x85,0x2a,0x52,0x5a,0xa0,0x92,0x98,0xb1,0x0c,0x59,0x38,0x50,0x46,0xc3,0xb5,
-0x82,0x5f,0x67,0x3f,0x68,0x8b,0x2c,0x97,0xdc,0x41,0xd7,0x05,0x64,0x03,0x2b,0x0a,
-0xbb,0xcd,0xaa,0xb9,0x26,0x3e,0x97,0x2e,0x10,0x8f,0x50,0x3d,0x64,0x2b,0x05,0x60,
-0x8b,0xd4,0xd1,0xb4,0x91,0x9f,0xb9,0x7b,0x03,0xeb,0x17,0x6a,0x19,0x81,0x02,0x82,
-0x91,0x20,0x6b,0xfd,0x0f,0xd0,0xb8,0x90,0xdf,0x89,0x1d,0x00,0xb5,0x25,0xff,0x17,
-0x1d,0x83,0xa6,0xb1,0x42,0xff,0x99,0x88,0xf3,0x3e,0x77,0x22,0x0a,0x07,0xb1,0x89,
-0x03,0x33,0xc4,0x5f,0xb9,0xe3,0xfe,0x43,0xf4,0x8c,0xfc,0x4f,0x3d,0x21,0xc7,0xd5,
-0xbd,0x48,0x0b,0x00,0x17,0x8e,0x9a,0xce,0x73,0x5a,0x5b,0x33,0xf0,0x09,0x9c,0x66,
-0x87,0xdc,0x43,0x78,0x19,0x03,0x30,0xdf,0xc6,0x1e,0x4d,0x0c,0x79,0x03,0x83,0xdc,
-0xe0,0x15,0x9e,0xa2,0x4a,0x27,0x45,0x56,0x98,0x3b,0xdc,0xa9,0x5d,0x44,0x7b,0xd1,
-0x8f,0x45,0x14,0x4d,0xf9,0x34,0xad,0xf9,0xf4,0x05,0xc9,0x18,0xfd,0x20,0x03,0xd0,
-0xf0,0x92,0x5f,0xfc,0x61,0x0b,0x28,0xbb,0xc6,0xf3,0x7f,0x43,0x0e,0x34,0x01,0xae,
-0xf4,0xdf,0xc1,0x63,0x2a,0x6a,0xe1,0x54,0x16,0x12,0x7d,0x99,0xd6,0x22,0xf7,0x25,
-0x79,0x82,0x26,0x8a,0x3f,0xb4,0xc5,0xf7,0xb9,0xed,0x85,0xd2,0x4f,0xeb,0xcf,0x48,
-0x18,0xdb,0x50,0xf1,0xf7,0x06,0x06,0xfb,0x58,0xe6,0x06,0xab,0x26,0x43,0x7f,0xd7,
-0x3f,0x5f,0x8e,0xbe,0xa1,0xa0,0x46,0x85,0x42,0x9e,0x6a,0x09,0x06,0x14,0x2d,0xe1,
-0x56,0x46,0xd0,0x07,0x3d,0x62,0xa8,0x22,0x4a,0xa4,0x7a,0x3d,0xbd,0x18,0x8b,0x16,
-0x60,0x94,0x21,0xf6,0x64,0xe1,0x1e,0xb0,0x7c,0xa9,0xaa,0x55,0x60,0xe3,0x45,0xdc,
-0x7d,0x86,0xfe,0x40,0x28,0xf6,0xa9,0x71,0xa2,0xb6,0x87,0xab,0x6f,0xf9,0xb5,0x68,
-0x13,0xb6,0xa0,0x16,0x8f,0x16,0xab,0x32,0x46,0x13,0x90,0x90,0x0e,0xd9,0x7d,0x8b,
-0xdd,0x53,0xa3,0xd5,0x3f,0x35,0x78,0xd3,0xda,0xe0,0x7d,0x46,0xba,0x6b,0x8a,0x91,
-0x45,0x29,0xd5,0xb0,0x9e,0x05,0x04,0x74,0x72,0xc4,0xae,0x68,0x87,0x01,0x48,0x01,
-0x16,0xe4,0x05,0xe5,0x6e,0xff,0x7d,0xb4,0x17,0x23,0x5d,0x3c,0x64,0x82,0x72,0x49,
-0xa1,0xa4,0xad,0xbc,0x87,0x2e,0xb1,0x0e,0x87,0x4e,0x88,0x99,0xb6,0x1d,0x13,0x87,
-0xce,0xc1,0x26,0xe0,0x59,0x2c,0x80,0xca,0xaa,0x89,0x81,0x22,0x0d,0xa9,0x75,0x85,
-0xd4,0x58,0xaa,0x3c,0x93,0x19,0x68,0x71,0x09,0xba,0x46,0xb4,0xdc,0x7b,0x48,0xe1,
-0x80,0xe3,0x2e,0x42,0x98,0xfa,0x9d,0x69,0xed,0x77,0xe0,0x6f,0xd9,0x8c,0x81,0x16,
-0xd0,0x90,0x79,0x28,0xba,0x46,0xb7,0x04,0x2d,0x72,0x00,0x8d,0xbf,0xd0,0xc4,0xa4,
-0x2e,0x72,0x5a,0xbb,0x48,0x4a,0x20,0x75,0x8c,0xee,0x97,0x71,0xc9,0xdf,0xe5,0x1e,
-0x51,0x93,0x74,0xcf,0xe8,0x84,0x5c,0x40,0x46,0x54,0xac,0x03,0xa9,0x7f,0x9f,0xd6,
-0xfe,0x1d,0xa2,0x8e,0x66,0x60,0x1a,0x3a,0x91,0x0a,0x94,0x88,0xd4,0x75,0xa5,0x69,
-0xe8,0x92,0x85,0xd1,0xf3,0x78,0xf7,0x09,0x06,0x85,0x76,0xc8,0xdf,0x1b,0x45,0x44,
-0x48,0x83,0x8e,0x69,0x1d,0x74,0xfc,0x47,0xb3,0x04,0x6a,0x86,0x4e,0xbe,0x25,0x72,
-0x74,0xbd,0x8f,0x6b,0x66,0x9a,0xa8,0x3e,0xe3,0xea,0x1a,0x64,0x44,0xb0,0xcb,0x53,
-0x0c,0xc9,0xfd,0xca,0x90,0x90,0x42,0xd2,0x3c,0x9b,0xb8,0x1f,0x0c,0x23,0x32,0x7b,
-0x05,0xd6,0x8e,0x8c,0xdd,0x45,0xe7,0x50,0x51,0x74,0x04,0x7a,0xa3,0x0b,0xec,0xdd,
-0x2c,0x56,0xb4,0x4c,0x68,0x35,0x5d,0xd5,0xa1,0xd5,0x55,0xe9,0x84,0xce,0x01,0xf1,
-0xa8,0x04,0xce,0x8a,0xd6,0x79,0x97,0x2e,0x36,0x97,0x35,0x0a,0x65,0xe1,0xc5,0x3a,
-0x89,0xcb,0xfa,0x04,0x53,0x82,0xb0,0x17,0xd1,0x27,0x13,0x1d,0x4e,0x57,0xb5,0x3d,
-0xa5,0x98,0xde,0xc0,0x0f,0xb0,0x85,0x09,0xd7,0x41,0x23,0x25,0x1c,0x24,0xb8,0xec,
-0xd2,0x1d,0xf0,0x1d,0x98,0xdd,0x57,0x7c,0x81,0x19,0xc2,0xf4,0x8b,0xe8,0x63,0xf2,
-0x62,0xee,0x55,0xc9,0x6b,0xb4,0xda,0x66,0x82,0xdd,0xe9,0x38,0xd8,0xbd,0x06,0x76,
-0x30,0xa4,0x85,0x68,0xa3,0xd7,0xab,0x42,0x43,0x65,0x69,0x6f,0x40,0x8c,0x94,0xb7,
-0xf8,0x9b,0xd0,0xf4,0x47,0x51,0x56,0x0e,0x76,0x0f,0x8a,0x4b,0x95,0x80,0xb0,0xa5,
-0xf3,0x4c,0x17,0x6a,0x25,0x81,0xc8,0x44,0xff,0x48,0x58,0xc6,0x44,0xff,0xdf,0x60,
-0x48,0x74,0x4d,0x92,0x1d,0x4e,0xc0,0x2f,0xc3,0x31,0xe0,0x97,0x8b,0x34,0x2b,0x63,
-0x21,0x1d,0xfb,0x2b,0xd7,0x70,0xa6,0xa1,0x14,0x62,0xc7,0x28,0x56,0x1f,0x06,0x36,
-0xce,0xcb,0x0e,0x04,0x48,0xbb,0x8a,0xd9,0x6e,0xa7,0x73,0x53,0xe4,0x8c,0xb7,0x22,
-0x73,0x9d,0x5c,0x97,0xa7,0x94,0x7a,0x83,0xe6,0x3c,0x88,0xa0,0xfc,0x7e,0xa6,0x59,
-0x31,0x49,0xa4,0x20,0x2b,0x25,0x1e,0x5e,0xad,0xa7,0xdb,0x7b,0x87,0x6b,0x1c,0x14,
-0x63,0xd1,0xe7,0x49,0xa8,0x93,0xdd,0x15,0xad,0xc6,0x18,0x93,0x19,0xe5,0x41,0x24,
-0xc9,0x77,0x86,0x73,0x24,0x99,0x2e,0xd1,0xe3,0x6a,0x2c,0xcc,0x64,0x29,0x61,0x32,
-0x36,0x66,0x81,0xaa,0x51,0x46,0x02,0xcd,0x9d,0x03,0x68,0xb5,0x96,0x3b,0x9d,0x78,
-0xdd,0x30,0x0f,0x6d,0x14,0x78,0xb0,0x5f,0xf6,0x99,0xea,0x35,0xe2,0xe4,0x76,0xec,
-0x34,0x1e,0xb8,0xfa,0x75,0x70,0x02,0x9a,0x0c,0xac,0x28,0x99,0xb9,0x4d,0x65,0x53,
-0x96,0xb6,0x5f,0xc2,0x06,0x1b,0xbf,0x40,0x34,0x9f,0xad,0x56,0xe6,0xe7,0x9f,0xae,
-0x54,0x17,0xe4,0x67,0xd6,0xd1,0x4b,0xb5,0x12,0x84,0xbe,0x15,0xf6,0x3a,0xf3,0x15,
-0xbf,0x57,0x24,0xab,0x47,0x8f,0x56,0xaa,0x8b,0xcf,0x54,0xe6,0x97,0x16,0x2b,0xf3,
-0x0b,0xa8,0x9b,0xa0,0xdd,0xfc,0x03,0xb7,0x83,0x43,0x44,0xbb,0x85,0x49,0xda,0x79,
-0x9c,0x03,0xf4,0xe3,0x53,0x78,0xa1,0x4b,0xb0,0x6a,0xf0,0x4d,0x29,0xb4,0x62,0x7d,
-0x40,0x81,0x2f,0x0c,0xce,0xb9,0xd8,0x29,0x1b,0x0b,0x5c,0xf6,0xc9,0x58,0x8e,0xb1,
-0x06,0xc8,0x08,0x83,0xf6,0xef,0x3e,0x0a,0x07,0x1f,0xb1,0x40,0x0b,0x9b,0xdf,0x7f,
-0x97,0x0e,0x04,0x76,0x2d,0xad,0xb1,0x60,0x2d,0xe0,0x41,0x95,0xe8,0x80,0x45,0xf7,
-0x2c,0x4a,0xd3,0xc0,0xd2,0xa2,0x14,0x6f,0xb9,0xe9,0x49,0x5d,0x25,0x72,0x99,0x2d,
-0xe4,0x64,0xaf,0xbb,0x86,0x9c,0xbb,0xaa,0x99,0x72,0xe2,0x6b,0xb9,0x3a,0x37,0xf7,
-0x0b,0xb4,0x99,0x64,0xb5,0xb3,0xeb,0x3b,0x1d,0xcb,0x3f,0x37,0xe6,0x74,0x83,0x3a,
-0x16,0xf1,0x6b,0xec,0xeb,0x0d,0xd4,0xd1,0x06,0xac,0x30,0x81,0x26,0xcc,0x29,0x69,
-0xef,0xf3,0xcb,0x0f,0x13,0xae,0x5d,0x0d,0x9e,0xce,0xa0,0x9d,0x55,0x6b,0x58,0x30,
-0xad,0x52,0x3d,0xfe,0x9e,0x64,0x67,0xf9,0x46,0x2f,0xbb,0xa8,0xa3,0x56,0xac,0xcc,
-0xd4,0x75,0x6d,0x69,0x56,0x6d,0xc6,0x9a,0xe0,0x8c,0x99,0x1c,0x51,0xcb,0x9f,0x31,
-0x1b,0xdb,0xaa,0x7e,0xe2,0xf5,0x17,0xd7,0x5f,0x3d,0xf9,0xab,0xca,0x1a,0xb6,0xd2,
-0x57,0x80,0xa8,0xd7,0x2d,0xbd,0xe5,0x34,0x97,0x4d,0x94,0xc9,0x64,0x6b,0xfd,0x0c,
-0x8e,0x34,0x1d,0xf7,0xbc,0x33,0x8e,0x1d,0x2c,0x3f,0x31,0xf7,0xf6,0xd4,0xb1,0x6d,
-0x9e,0xd7,0x88,0x0d,0xc5,0x6f,0x79,0x7e,0xea,0x18,0x3e,0x94,0x73,0x0c,0xcf,0x9f,
-0x5c,0x03,0xd9,0x9e,0x2c,0xc9,0xfc,0xf4,0x1a,0xda,0x54,0x05,0x3a,0x2b,0x47,0x48,
-0xb8,0xa2,0xcd,0x7d,0xdd,0xa5,0xa9,0xb7,0x70,0xcc,0x62,0xd3,0xf1,0x3b,0x25,0x53,
-0x85,0x4f,0x20,0x2e,0x6b,0x47,0x5c,0xc1,0x46,0x71,0x4d,0xe2,0x25,0x9d,0x05,0x26,
-0x47,0xdb,0x70,0x26,0x8c,0x01,0xbb,0xb8,0x3d,0xb8,0x76,0x04,0xb1,0xe2,0xe7,0xb5,
-0x23,0x46,0x4a,0x21,0xcb,0x72,0xbf,0x34,0xa7,0x9e,0x7a,0xaa,0xd4,0xf6,0xac,0xe6,
-0x6b,0x2f,0xfc,0xe6,0x84,0xd7,0x28,0x99,0x9b,0x3b,0xeb,0x0a,0x48,0x85,0xe7,0x08,
-0x66,0x4c,0x40,0x34,0xa7,0x66,0xc4,0x78,0xac,0xf2,0xfc,0xca,0xd4,0xdb,0xc4,0x9b,
-0x5d,0xb3,0x1c,0x09,0x98,0xdf,0xa4,0xa7,0xf2,0xa6,0xa0,0xd7,0x38,0xfa,0x57,0x81,
-0xcc,0xc2,0xdc,0x9e,0xab,0x99,0x1b,0x6d,0xaf,0x71,0xc6,0x4c,0x7b,0x5a,0x8d,0xcf,
-0x6a,0x15,0x7c,0xa9,0x06,0x1d,0x3a,0xd9,0x53,0x38,0xf4,0xf0,0xb1,0x36,0xbd,0x42,
-0x86,0xa3,0x6b,0x1c,0x55,0x9f,0x14,0xcb,0x3f,0xd4,0xc7,0xb3,0x46,0x3d,0xd4,0xe7,
-0xa2,0xf2,0xaf,0xc6,0x4d,0xd0,0xf5,0xb0,0x1b,0x6a,0x92,0xf9,0xc9,0x87,0x32,0xbd,
-0x54,0xc6,0x47,0x4e,0x2b,0x96,0x06,0x03,0x3b,0x8e,0xde,0xda,0xc1,0xb1,0x1d,0x6f,
-0xa7,0x02,0x2a,0xca,0xf9,0x90,0x8a,0x3a,0x6e,0x09,0xe3,0x97,0x3d,0x1f,0xf3,0x76,
-0xb5,0x56,0xdb,0xb2,0xc3,0xe3,0xcf,0x9f,0x2a,0xe1,0x34,0x12,0xde,0x09,0x4b,0xc1,
-0x70,0x5c,0xae,0xc1,0x0a,0xe2,0x5c,0x46,0xc9,0x9e,0xa9,0xda,0x0b,0x8a,0xa7,0x99,
-0x75,0xe2,0x91,0x00,0x28,0xc7,0x38,0xf9,0xa6,0x56,0x47,0xa5,0xab,0x63,0xe9,0x00,
-0x36,0xe5,0x68,0x72,0xa6,0x53,0x34,0xe4,0x6c,0x66,0x01,0xbf,0x67,0x84,0xb6,0xfc,
-0xa2,0xf4,0xc4,0x1c,0x64,0xee,0x58,0xf6,0x04,0x28,0x0f,0xd2,0xfe,0x17,0x70,0x67,
-0x1c,0xe1,0x58,0x3b,0x00,0x00,};
+0x80,0x33,0x9a,0xb4,0x67,0xec,0xc2,0xaa,0xa5,0xd1,0x72,0x9a,0x4d,0x1b,0x6b,0x87,
+0xb2,0x31,0xe3,0x26,0x96,0x42,0xb8,0x8e,0x3a,0x01,0xe0,0xa4,0x61,0x2e,0x71,0x99,
+0x0c,0xb7,0xe0,0x49,0x70,0xf3,0x2e,0xc6,0x7d,0x40,0x30,0x70,0x80,0xd6,0x8e,0xda,
+0x5c,0x72,0xc8,0x6a,0x1b,0xec,0x58,0xbd,0xb0,0xa5,0x54,0x36,0xbe,0x4e,0xd5,0x95,
+0xef,0x8a,0x95,0x35,0x49,0x3f,0xa1,0x74,0x7b,0xc9,0xba,0xd6,0x87,0x09,0xb1,0xb3,
+0xf6,0x34,0x7b,0x1d,0xdb,0x56,0x59,0xe9,0x8a,0x05,0x6e,0xa2,0x5c,0xe3,0xaf,0x43,
+0x11,0x37,0x03,0x5b,0xae,0xf5,0x19,0xd1,0x9e,0x81,0x45,0x36,0x86,0xfd,0x6a,0xa5,
+0x1d,0xc1,0xff,0x61,0xd9,0xd5,0x8c,0x5e,0xf7,0xc2,0xc6,0x18,0x15,0xf9,0xa7,0xe4,
+0x76,0xdc,0xa5,0x82,0xbd,0x4b,0x62,0xf0,0x91,0x9e,0x60,0x71,0x70,0x12,0x15,0xd7,
+0x15,0x48,0xad,0x7e,0xb9,0x6a,0xa3,0x4e,0x37,0x65,0x6c,0x6a,0x0a,0x2f,0x06,0x2b,
+0x90,0xe5,0xea,0x7c,0x05,0x55,0xc8,0xd2,0xf3,0x2f,0xac,0x19,0xb8,0x5e,0x9e,0x9b,
+0x9b,0x32,0xa2,0xef,0xa4,0x0e,0xc7,0x35,0x36,0xd6,0x08,0xee,0xcc,0x18,0x10,0x28,
+0xe4,0xef,0xa0,0xd9,0x8f,0xf8,0xab,0xcb,0x80,0x69,0xbd,0x2a,0x5f,0xa6,0x2c,0x57,
+0xab,0x99,0x1e,0xab,0xaa,0x47,0x49,0x79,0x40,0x65,0xcc,0xd1,0x40,0x2a,0xbb,0x87,
+0x4a,0xc4,0xa5,0xfe,0x1f,0xa3,0xdb,0xe8,0xfa,0x3a,0xba,0xbc,0x87,0x17,0x88,0xf9,
+0x46,0x57,0xd9,0xca,0xd5,0xb9,0x4c,0x87,0x73,0xaa,0xc3,0x4f,0xd0,0x8a,0x90,0x6e,
+0x33,0x5b,0x2b,0x68,0xf7,0x6c,0xda,0xec,0x59,0xd5,0xea,0x8a,0x24,0x7e,0x92,0x46,
+0x17,0xb6,0x3a,0x9a,0xb6,0x3a,0xaa,0x5a,0x7d,0x8b,0x98,0x8a,0x3b,0x9b,0x40,0x0a,
+0x88,0x09,0xf2,0x36,0x26,0x4d,0xb8,0xc3,0xea,0xaf,0x96,0x1c,0xd4,0x0b,0x4b,0x98,
+0xc8,0xbf,0xa2,0x2b,0x22,0x4f,0x5f,0xf0,0x23,0xfc,0x20,0x63,0x48,0x29,0x0a,0xd0,
+0x3d,0x93,0x8e,0xf3,0x4c,0x3c,0x27,0x49,0x48,0x1f,0xb9,0xe7,0xa7,0xd3,0x9e,0x9f,
+0x56,0x3d,0xff,0x83,0x91,0x21,0x37,0x32,0x00,0x14,0xb7,0x44,0xa9,0xd2,0xf7,0x04,
+0xe8,0xc1,0x9f,0x2f,0x21,0x06,0x5c,0x27,0xc7,0x8c,0x0b,0xe7,0xb2,0x94,0x8e,0xb8,
+0xa4,0x46,0xbc,0x9a,0x54,0xd5,0x59,0xd4,0x9d,0x90,0x56,0x18,0xed,0x63,0x7c,0x7b,
+0x43,0x62,0xda,0x5d,0xdc,0xfd,0x05,0xe3,0xa2,0x44,0x55,0x38,0xee,0x62,0x3a,0xee,
+0xa2,0x1a,0xf7,0x0a,0x44,0xf6,0xae,0xf0,0x28,0x5b,0xd0,0x1d,0x1a,0x3f,0xcb,0x21,
+0x8c,0x83,0x5b,0xa1,0x0d,0x32,0x8f,0xfe,0x05,0x19,0x77,0xb7,0x2c,0x8e,0x0b,0x4a,
+0x58,0xc0,0xbe,0x85,0x0a,0xdc,0xa1,0x52,0x9b,0x85,0xe5,0x05,0x6a,0xcd,0x57,0xfd,
+0xcb,0x08,0xc2,0xdf,0x41,0x17,0xb2,0xe1,0x4e,0x27,0x1c,0x37,0xc7,0xf4,0x90,0x28,
+0xde,0x82,0x02,0xff,0xb1,0x80,0xf8,0x09,0x93,0xbe,0xcb,0x30,0x9e,0xe4,0x10,0x35,
+0x01,0x01,0xfb,0x17,0xca,0xd8,0x0d,0x70,0x1b,0x1f,0xa0,0x50,0x80,0x17,0x9f,0x42,
+0x15,0x29,0x2d,0x50,0x49,0xcc,0x58,0x86,0x2c,0x1c,0x28,0xa3,0xe1,0x5a,0xc1,0xaf,
+0xb3,0x1f,0xb4,0x45,0xce,0x4b,0xee,0xa0,0xeb,0x02,0xb2,0x81,0x15,0x85,0xdd,0x66,
+0xd5,0x5c,0x13,0x9f,0x0b,0x19,0x88,0x4e,0xa8,0x1e,0xb2,0xb1,0x02,0xb0,0x45,0xea,
+0x68,0xda,0xc8,0xcf,0xdc,0xbd,0x81,0xd5,0x0c,0xb5,0xa8,0x40,0x01,0xc1,0x48,0x90,
+0xb5,0xfe,0x07,0x68,0x5c,0xc8,0xef,0xc4,0x0e,0x80,0xda,0x52,0x0d,0x10,0x1d,0x83,
+0xa6,0xb1,0x5e,0xff,0x99,0x88,0xf3,0x3e,0xf7,0x25,0x0a,0x07,0xb1,0xa5,0x03,0x33,
+0xc4,0x5f,0xb9,0xe3,0x6e,0x44,0xf4,0x8c,0x6c,0x50,0x3d,0x21,0xc7,0xd5,0xbd,0x48,
+0x0b,0x00,0x17,0x8e,0x9a,0xce,0x73,0x5a,0x5b,0x33,0xf0,0x09,0x9c,0x66,0x87,0xdc,
+0x51,0x78,0x19,0x03,0x30,0xfb,0xc6,0x8e,0x4d,0x0c,0x79,0x03,0x83,0xdc,0xe0,0x15,
+0x9e,0xa2,0x66,0x27,0x25,0x57,0x98,0x3b,0xdc,0xa9,0x3d,0x45,0x7b,0xd1,0x8f,0x45,
+0x14,0x4d,0xf9,0x34,0xad,0xf9,0xf4,0x05,0xc9,0x18,0xfd,0x20,0x03,0xd0,0xf0,0x92,
+0x5f,0xfc,0x61,0x43,0x28,0xbb,0xc6,0xf3,0x7f,0x43,0x0e,0x34,0x01,0xae,0xf4,0xdf,
+0xc1,0x63,0x2a,0x6a,0xe1,0x54,0x16,0x12,0x7d,0x99,0xd6,0x22,0xf7,0x25,0x79,0x82,
+0x26,0x8a,0x3f,0xb4,0xc5,0xf7,0xb9,0x09,0x86,0xd2,0x4f,0xeb,0xcf,0xb8,0x18,0x9b,
+0x52,0xf1,0xf7,0x06,0x06,0xfb,0x58,0xe6,0x06,0xab,0x26,0x43,0x7f,0xd7,0x3f,0x5f,
+0x8e,0xbe,0xa1,0xa0,0x46,0x85,0x42,0x9e,0x6a,0x09,0x06,0x14,0x2d,0xe1,0xc6,0x46,
+0xd0,0x07,0x3d,0x62,0xa8,0x22,0x4a,0xa4,0x7a,0x3d,0xbd,0x18,0x8b,0x16,0x60,0x94,
+0x21,0xf6,0x64,0xe1,0x1e,0xb0,0x7c,0xa9,0x6a,0x57,0x60,0xe3,0x45,0xdc,0x7d,0x86,
+0xfe,0x40,0x28,0xf6,0xa9,0x71,0xa2,0xd2,0x87,0xab,0x6f,0xf9,0xb5,0x68,0x13,0x36,
+0xa4,0x16,0x8f,0x16,0xab,0x32,0x46,0x13,0x90,0x90,0x0e,0xd9,0x8b,0x8b,0xbd,0x54,
+0xa3,0xd5,0x3f,0x35,0x78,0xd3,0xda,0xe0,0x7d,0x46,0xba,0x6b,0x8a,0x91,0x45,0x29,
+0xd5,0xb0,0xba,0x05,0x04,0x74,0x72,0xc4,0xae,0x68,0x87,0x01,0x48,0x01,0x96,0xe7,
+0x05,0xe5,0x6e,0xff,0x7d,0xb4,0x17,0x23,0x5d,0x3c,0x64,0x82,0x72,0x49,0xa1,0xa4,
+0xad,0xbc,0x87,0x2e,0xb1,0x2a,0x87,0x4e,0x88,0x99,0xb6,0x1d,0x13,0x87,0xce,0xc1,
+0x26,0xe0,0x59,0x2c,0x80,0xca,0xaa,0x89,0x81,0x22,0x0d,0xa9,0x75,0x85,0xd4,0x58,
+0xaa,0x3c,0x93,0x19,0x68,0x71,0x09,0xba,0x46,0xb4,0xdc,0x89,0x48,0xe1,0x80,0xe3,
+0x2e,0x42,0x98,0xfa,0x9d,0x69,0xed,0x77,0xe0,0x6f,0xd9,0x8c,0x81,0x16,0xd0,0x90,
+0x79,0x28,0xc1,0x46,0xb7,0x04,0x2d,0x32,0x02,0x8d,0xbf,0xd0,0xc4,0xa4,0x2e,0x72,
+0x5a,0xbb,0x48,0x4a,0x20,0x75,0x8c,0xee,0x97,0x71,0xc9,0xdf,0xe5,0x1e,0x51,0x93,
+0x74,0xcf,0xe8,0x84,0x5c,0x40,0x7e,0x54,0xac,0x03,0xa9,0x7f,0x9f,0xd6,0xfe,0x1d,
+0xa2,0x8e,0x66,0x60,0x1a,0x3a,0x91,0x7a,0x94,0x88,0xd4,0x75,0xa5,0x69,0xe8,0x92,
+0x65,0xd2,0xf3,0x78,0xf7,0x09,0x06,0x85,0x76,0xc8,0xdf,0x1b,0x45,0x44,0x48,0x83,
+0x8e,0x69,0x1d,0x74,0xfc,0x47,0xb3,0x04,0x6a,0x86,0x4e,0xbe,0x25,0x72,0x74,0xbd,
+0x8f,0x6b,0xe6,0x9d,0xa8,0x45,0xe3,0xea,0x1a,0x64,0x44,0xb0,0xcb,0x53,0x0c,0xc9,
+0xdd,0xcb,0x90,0x90,0x42,0xd2,0x3c,0x9b,0xb8,0x1f,0x0c,0x23,0x32,0x7b,0x05,0xd6,
+0x8e,0x8c,0xdd,0x45,0xe7,0x50,0x51,0x74,0x04,0x7a,0xa3,0x0b,0xec,0xe4,0x2c,0x56,
+0xb4,0x4c,0x68,0x35,0x5d,0xd5,0xa1,0xd5,0x55,0xe9,0x84,0xce,0x01,0xf1,0xa8,0x04,
+0xce,0x8a,0xd6,0x79,0x97,0x2e,0x36,0x97,0x15,0x0b,0x65,0xe1,0xc5,0x3a,0x89,0xcb,
+0xfa,0x04,0x53,0x82,0xb0,0x17,0xd1,0x27,0x13,0x1d,0x4e,0x57,0xb5,0x3d,0xa5,0x98,
+0xde,0xc0,0x0f,0xb0,0x85,0x09,0xd7,0x41,0x23,0x25,0x1c,0x24,0xb8,0xec,0xd9,0x1d,
+0xf0,0x1d,0x98,0xdd,0x57,0x7c,0x81,0x19,0xc2,0xf4,0x8b,0xe8,0x63,0xf2,0x62,0xee,
+0x55,0x01,0x6c,0xb4,0xda,0x66,0x82,0xdd,0xe9,0x38,0xd8,0xbd,0x06,0x76,0x30,0xa4,
+0x85,0x68,0xa3,0xd7,0xab,0x42,0x43,0x65,0x69,0x6f,0x40,0x8c,0x94,0xb7,0xf8,0x9b,
+0xd0,0xf4,0x47,0x51,0x56,0x0e,0x76,0x0f,0x8a,0x4b,0x95,0x80,0xb0,0xa5,0xf3,0x4c,
+0x97,0x6d,0x25,0x81,0xc8,0x44,0xff,0x48,0x58,0xc6,0x44,0xff,0xdf,0x60,0x48,0x74,
+0x4d,0x92,0x1d,0x4e,0xc0,0x2f,0xc3,0x31,0xe0,0x97,0x8b,0x34,0x2b,0x63,0x59,0x1d,
+0xbb,0x2d,0xd7,0x70,0xc2,0xa1,0x14,0x62,0xff,0x28,0xd6,0x22,0x06,0xb6,0xd1,0xcb,
+0x7e,0x04,0x48,0xbb,0x8a,0xd9,0x6e,0xa7,0x73,0x53,0xe4,0x8c,0x37,0x26,0x73,0xd5,
+0x5c,0x17,0xab,0x94,0x7a,0x83,0xe6,0x3c,0x96,0xa0,0xfc,0x7e,0xa6,0x59,0x31,0x49,
+0xa4,0x3c,0x2b,0x05,0x1f,0x5e,0xad,0xa7,0x9b,0x7d,0x87,0x2b,0x1e,0x14,0x63,0xd1,
+0xe7,0x49,0xa8,0x93,0xdd,0x23,0xad,0xc6,0x18,0x93,0x19,0xe5,0x41,0x24,0xc9,0x77,
+0x86,0x73,0x24,0x99,0x2e,0xd8,0xe3,0x6a,0x2c,0xcc,0x64,0x61,0x61,0x32,0x36,0x66,
+0x81,0xaa,0x51,0x46,0x02,0xcd,0x9d,0x0a,0x68,0xb5,0x96,0x3b,0x9d,0x78,0x15,0x31,
+0x0f,0x6d,0x14,0x78,0xb0,0x5f,0x76,0x9d,0xea,0x15,0xe3,0xe4,0x76,0xec,0x34,0x1e,
+0xb8,0x16,0x76,0x70,0x02,0x9a,0x0c,0xac,0x28,0x99,0xb9,0x4d,0x65,0x53,0x16,0xba,
+0x5f,0xc2,0x76,0x1b,0xbf,0x40,0x34,0x9f,0xad,0x56,0xe6,0xe7,0x9f,0xae,0x54,0x17,
+0xe4,0x67,0xd6,0xd1,0x4b,0xb5,0x12,0x84,0xbe,0x15,0xf6,0x3a,0xf3,0x15,0xbf,0x57,
+0x24,0xab,0x47,0x8f,0x56,0xaa,0x8b,0xcf,0x54,0xe6,0x97,0x16,0x2b,0xf3,0x0b,0xa8,
+0x9b,0xa0,0xdd,0xfc,0x03,0xb7,0x83,0x43,0x44,0xbb,0x85,0x49,0xda,0x79,0x9c,0x03,
+0xf4,0xe3,0x53,0x78,0xa1,0x4b,0xb0,0x6a,0xf0,0x4d,0x29,0xb4,0x62,0x7d,0x40,0xb9,
+0x2f,0x0c,0xce,0xb9,0xd8,0x37,0x1b,0x0b,0x5c,0xf6,0xc9,0x58,0x8e,0xb1,0x22,0xc8,
+0x08,0x83,0xf6,0xef,0x3e,0x0a,0x07,0x1f,0xb1,0x5c,0x0b,0x9b,0xdf,0x7f,0x97,0x0e,
+0x04,0x76,0x2d,0xad,0xb1,0x60,0x65,0xe0,0x41,0x95,0xe8,0x80,0x25,0xf8,0x2c,0x4a,
+0xd3,0xc0,0x42,0xa3,0x94,0x72,0xb9,0x05,0x4a,0x5d,0x25,0x72,0x99,0x2d,0xe4,0x64,
+0xaf,0xbb,0x86,0x9c,0xc2,0xaa,0x99,0x72,0xfe,0x6b,0xb9,0x3a,0x37,0xf7,0x0b,0xb4,
+0x99,0x64,0xed,0xb3,0xeb,0x3b,0x1d,0xcb,0x3f,0x37,0xe6,0xac,0x83,0x3a,0x24,0xf1,
+0x6b,0xec,0xf2,0x0d,0xd4,0x41,0x07,0xac,0x37,0x81,0x26,0xcc,0x29,0x69,0xef,0xf3,
+0x8b,0x11,0x13,0xae,0x64,0x0d,0x9e,0xd5,0xa0,0x9d,0x55,0x2b,0x5a,0x30,0xad,0x52,
+0x4b,0xfe,0x9e,0x64,0x67,0xf9,0x46,0x2f,0xc2,0xa8,0x83,0x57,0xac,0xcc,0xd4,0x75,
+0x6d,0x69,0x56,0x6d,0xcd,0x9a,0xe0,0xc4,0x99,0x1c,0x58,0xcb,0x9f,0x38,0x1b,0xdb,
+0xaa,0x7e,0xe2,0xf5,0x17,0xd7,0x5f,0x3d,0xf9,0xab,0xca,0x1a,0x36,0xd6,0x57,0x80,
+0xa8,0xd7,0x2d,0xbd,0xe5,0x34,0x97,0x4d,0x94,0xc9,0x64,0xa3,0xfd,0x0c,0x0e,0x38,
+0x1d,0xf7,0xbc,0x33,0x8e,0x1d,0x2c,0x3f,0x31,0xf7,0xf6,0xd4,0xb1,0x6d,0x9e,0xde,
+0x88,0x0d,0xc5,0x6f,0x79,0x9a,0xea,0x18,0x3e,0x94,0x53,0x0d,0xcf,0x9f,0x5c,0x03,
+0xd9,0x9e,0x2c,0xc9,0xfc,0xf4,0x8a,0xda,0x54,0x05,0x3a,0x2b,0x07,0x4a,0xb8,0xbe,
+0xcd,0x5d,0xde,0xa5,0xa9,0xb7,0x70,0xe8,0x62,0xd3,0xf1,0x3b,0x25,0x53,0x85,0x4f,
+0x20,0x2e,0x6b,0x47,0x5c,0xcf,0x46,0x71,0x4d,0xe2,0x25,0x9d,0x05,0x26,0x07,0xdd,
+0x70,0x42,0x8c,0x01,0xbb,0xb8,0x3d,0xb8,0x76,0x04,0xb1,0xe2,0xe7,0xb5,0x23,0x46,
+0x4a,0x21,0x8b,0x74,0xbf,0x34,0xa7,0x9e,0x7a,0xaa,0xd4,0xf6,0xac,0xe6,0x6b,0x2f,
+0xfc,0xe6,0x84,0xd7,0x28,0x99,0x9b,0x3b,0xeb,0x0a,0x48,0x85,0xa7,0x0a,0x66,0x4c,
+0x40,0x34,0xa7,0x66,0xc4,0x78,0xac,0xf2,0x34,0xcb,0xd4,0xdb,0xc4,0x9b,0x5d,0xc1,
+0x1c,0x09,0x98,0xdf,0xa4,0x67,0xf4,0xa6,0xa0,0xd7,0x38,0x08,0x58,0x81,0xcc,0xc2,
+0xdc,0x9e,0xab,0x99,0x1b,0x6d,0xaf,0x71,0xc6,0x4c,0x7b,0x5a,0x8d,0x4f,0x6e,0x15,
+0x7c,0xa9,0x06,0x1d,0x3a,0xe7,0x53,0x38,0xf4,0xf0,0x21,0x37,0xbd,0x5e,0x86,0x83,
+0x6c,0x1c,0x55,0x9f,0x1b,0xcb,0x3f,0xd4,0x87,0xb5,0x46,0x3d,0xd4,0xa7,0xa4,0xf2,
+0xaf,0xc6,0x4d,0xd0,0xf5,0xb0,0x37,0x6a,0x92,0xf9,0xc9,0x87,0x32,0xbd,0x54,0xc6,
+0x47,0x4e,0x2b,0x96,0x06,0x03,0xfb,0x8f,0xde,0xda,0xc1,0x21,0x1e,0x6f,0xa7,0x02,
+0x2a,0xca,0x69,0x91,0x8a,0x3a,0x7c,0x09,0xe3,0x97,0x3d,0x2d,0xf3,0x76,0xb5,0x56,
+0xdb,0xb2,0xc3,0xe3,0xcf,0x9f,0x2a,0xe1,0x6c,0x12,0xde,0x09,0x4b,0xc1,0x70,0x5c,
+0xae,0xc1,0x0a,0xe2,0x94,0x46,0xc9,0x9e,0xa9,0xda,0x0b,0x8a,0xa7,0x99,0x55,0xe3,
+0x91,0x00,0x28,0xc7,0x38,0x07,0xa7,0xd6,0x4a,0xa5,0xab,0x63,0xe9,0x00,0x36,0xe5,
+0x68,0x72,0xa6,0x53,0x34,0xe4,0xa4,0x66,0x01,0xbf,0x67,0x84,0xb6,0xfc,0xa2,0xf4,
+0xc4,0x1c,0x64,0xee,0x58,0xf6,0x3c,0x28,0x8f,0xd5,0xfe,0x17,0x7f,0x96,0xc7,0xd6,
+0x66,0x3b,0x00,0x00,};
 
-static const unsigned int dummy_align__ups_history_html = 10;
+static const unsigned int dummy_align__ups_history_html = 11;
 static const unsigned char data__ups_history_html[] = {
 /* /ups_history.html (18 chars) */
 0x2f,0x75,0x70,0x73,0x5f,0x68,0x69,0x73,0x74,0x6f,0x72,0x79,0x2e,0x68,0x74,0x6d,
@@ -2966,8 +3039,16 @@ sizeof(data__rotek_png) - 12,
 1,
 }};
 
-const struct fsdata_file file__settings_html[] = { {
+const struct fsdata_file file__rslogin_html[] = { {
 file__rotek_png,
+data__rslogin_html,
+data__rslogin_html + 16,
+sizeof(data__rslogin_html) - 16,
+1,
+}};
+
+const struct fsdata_file file__settings_html[] = { {
+file__rslogin_html,
 data__settings_html,
 data__settings_html + 16,
 sizeof(data__settings_html) - 16,
@@ -2983,5 +3064,5 @@ sizeof(data__ups_history_html) - 20,
 }};
 
 #define FS_ROOT file__ups_history_html
-#define FS_NUMFILES 11
+#define FS_NUMFILES 12
 

+ 281 - 302
modules/HTTP_Server/http_server.c

@@ -18,6 +18,7 @@
 #include "megatec.h"
 #include "log.h"
 #include "hal.h"
+#include "radius_user.h"
 
 #ifdef PRINTF_STDLIB
 #include <stdio.h>
@@ -106,6 +107,9 @@ unsigned long log_ptr = 0;
 unsigned long log_size = 0;
 bool fLogTransInprog = false;
 
+
+static bool fl_raddius_net_err = false;
+
 /**
   * @brief  Общая структура настроек
   */
@@ -1587,9 +1591,11 @@ void HTTP_UPSTest(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBuf
 	  char tempValue[20];
 	  char tempValue2[20];
 	  int8_t res = 0;
+	  char log_string[50];
 
 	  memset(tempValue, 0, 20);
 	  memset(tempValue2, 0, 20);
+	  memset(log_string, 0,50);
 
 	  strcpy(bufOut, HTTP_200_OK);
 
@@ -1598,7 +1604,9 @@ void HTTP_UPSTest(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBuf
 		  res = ups_metac_service_pdu(ups_cancel_test);
 		  if(res == 1 || res == 0){
 			  strcat(bufOut, "Тест остановлен!");
-			  log_event_data(LOG_TEST_UPS, "Администратор(Останов)");
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Останов)");
+			  log_event_data(LOG_TEST_UPS, log_string);
 		  }
 		  if(res == -1)
 			  strcat(bufOut, "Тест не удалось остановить!");
@@ -1608,7 +1616,9 @@ void HTTP_UPSTest(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBuf
 		  res = ups_metac_service_pdu(ups_test_low_bat);
 		  if(res == 1 || res == 0){
 			  strcat(bufOut, "Тест запущен!");
-			  log_event_data(LOG_TEST_UPS, "Администратор (Запущен)");
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Запущен)");
+			  log_event_data(LOG_TEST_UPS, log_string);
 		  }
 		  if(res == -1)
 			  strcat(bufOut, "Тест не удалось запустить!");
@@ -1620,7 +1630,9 @@ void HTTP_UPSTest(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBuf
 		  res = ups_metac_service_pdu(ups_test_time);
 		  if(res == 1 || res == 0){
 			  strcat(bufOut, "Тест запущен!");
-			  log_event_data(LOG_TEST_UPS, "Администратор (Запущен)");
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Запущен)");
+			  log_event_data(LOG_TEST_UPS, log_string);
 		  }
 		  if(res == -1)
 			  strcat(bufOut, "Тест не удалось запустить!");
@@ -1638,8 +1650,10 @@ void HTTP_UPSshutdown(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *le
 	  char tempValue[50];
 	  char tempValue2[50];
 	  int8_t res = 0;
+	  char log_string[50];
 
 	  memset(tempValue, 0, 50);
+	  memset(log_string, 0,50);
 
 	  strcpy(bufOut, HTTP_200_OK);
 
@@ -1647,7 +1661,9 @@ void HTTP_UPSshutdown(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *le
 	  if (strcmp(tempValue, "reboot") == 0){
 		  res = ups_metac_service_pdu(ups_cancel_shut_down);
 		  if(res == 1){
-			  log_event_data(LOG_SHUTDOWN_UPS, "Администратор(Останов)");
+			  strcpy(log_string, name_login);
+			  strcat(log_string, " (Останов)");
+			  log_event_data(LOG_SHUTDOWN_UPS, log_string);
 			  strcat(bufOut, "Выключение нагрузки ИБП отменено!");
 		  }
 		  else
@@ -1661,7 +1677,7 @@ void HTTP_UPSshutdown(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *le
 		  res = ups_metac_service_pdu(ups_shutdown);
 		  if(res == 1){
 			  strcat(bufOut, "Отключение нагрузки ИБП!");
-			  log_event_data(LOG_SHUTDOWN_UPS, "Администратор");
+			  log_event_data(LOG_SHUTDOWN_UPS, name_login);
 		  }else
 			  strcat(bufOut, "Отключение нагрузки ИБП не удалось!");
 		  *lenBufOut = strlen(bufOut);
@@ -1697,6 +1713,8 @@ void HTTP_ConfirmBootPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t
   }
 }
 
+
+
 /**
   * @brief  Проверка пароля для входа в Web
   * @retval None
@@ -1710,96 +1728,129 @@ int HTTP_ConfirmWebPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *l
 	  char *strPtr = 0;
 	  char WebPassword[MAX_WEB_PASSWD_LEN];
 	  char WebLogin[MAX_WEB_LOGIN_LEN];
-	  char buf[40];
 
 	  memset(login, 0, 20);
 	  memset(password, 0, 20);
 	  memset(tempStr, 0, 50);
 
+	  memset(name_login, 0, 50);
+
 	  /* Get first 50 bytes of string */
 	  strncpy(tempStr, bufIn, 49);
 
 	  /* Add " " to the string in order GetParamValue() can be able to parse the param */
 	  strcat(tempStr, " ");
+	  GetParamValue(tempStr, "login=", login, &valueLen);
+	  GetParamValue(tempStr, "password=", password, &valueLen);
+
+	  if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)){
+		  switch(RC_Login(login, password)){
+		  case RC_ERROR:
+			  Authenticated = false;
+			  break;
+		  case RC_LOGIN_ADMIN_OK:
+			  Authenticated = true;
+			  user_id = 0;
+			  break;
+		  case RC_LOGIN_USER_OK:
+			  Authenticated = true;
+			  user_id = 1;
+			  break;
+		  case RC_NET_ERR:
+			  Authenticated = false;
+			  fl_raddius_net_err = true;
+			  strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
+			  strcat(bufOut,"<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/login.html\" /></head><center><h2>Ошибка соединения с RADIUS сервером</h2></center></html>");
+			  *lenBufOut = strlen(bufOut);
+			  return SEND_REQUIRED_NO;
+			  break;
+		  case RC_ACC_DENIED:
+			  Authenticated = false;
+			  break;
+		  default:
+			  break;
+		  }
+	  }
+	  else{
+		  for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
 
-	  if (GetParamValue(tempStr, "login=", login, &valueLen) &&
-	      GetParamValue(tempStr, "password=", password, &valueLen))
-	  {
-	      for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
-
-	        GetUserLogin(user_id, WebLogin, &valueLen);
-	        GetUserPassword(user_id, WebPassword, &valueLen);
-
-	        /* Check login and password */
-	        if ((strncmp(WebLogin, login, MAX_WEB_LOGIN_LEN) == 0) &&
-	            (strncmp(WebPassword, password, MAX_WEB_PASSWD_LEN) == 0)) {
-
-	            /* Login and pass are valid */
-
-	            /* Check user's login session */
-	            /* If "user" has logged in */
-	            if (user_id >= 1) {
-
-	            }
-
-            /* TODO replace global flag with user-pass-cookie */
-            Authenticated = true;
-
-            /* Generate cookie */
-            sprintf(tempStr, "%X", (unsigned int)GetRandomNumber());
-
-            /* Set users cookie */
-            HTTP_SetUserCookie(tempStr, user_id);
-
-            HTTP_UpdateUserLoginTime(user_id);
-
-            /* Send login and cookie back */
-            strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\nSet-Cookie: uname=");
-            strcat(bufOut, WebLogin);
-            strcat(bufOut, "\r\nSet-Cookie: id=");
-            strcat(bufOut, tempStr);
-            sprintf(tempStr, "%d", user_id);
-            strcat(bufOut, "\r\nSet-Cookie: role=");
-            strcat(bufOut, tempStr);
-            if(sSettings.sRADIUS.Auth_enable)
-				strcat(bufOut, "\r\nSet-Cookie: auth=1");
-			else
-				strcat(bufOut, "\r\nSet-Cookie: auth=0");
-            strcat(bufOut, "\r\n\r\n");
-            strcat(bufOut,"<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/index.html\"/></head></html>\r\n\r\n");
-
-            *lenBufOut = strlen(bufOut);
-
-            switch (user_id) {
-                case 0:
-                    snprintf(buf, sizeof(buf), "Администратор");
-                    break;
-                case 1:
-                    snprintf(buf, sizeof(buf), "Пользователь");
-                    break;
-                default:
-                    snprintf(buf, sizeof(buf), "", login);
-                    break;
-            }
+		        GetUserLogin(user_id, WebLogin, &valueLen);
+		        GetUserPassword(user_id, WebPassword, &valueLen);
 
-            log_event_data(LOG_LOGIN, buf);
-            /* Запускаем задачу-таймер логаута. */
-            /* TODO отправить ответ серверу о статусе пароля */
-            return SEND_REQUIRED_YES;
-        }
-        /*
-        else {
-            continue;
-        }
-        */
-      }
-    }
-    /* No valid login and pass found */
+		        /* Check login and password */
+		        if ((strncmp(WebLogin, login, MAX_WEB_LOGIN_LEN) == 0) &&
+		            (strncmp(WebPassword, password, MAX_WEB_PASSWD_LEN) == 0)) {
 
-    /* TODO replace global flag with user-pass-cookie*/
-    Authenticated = false;
-    /* Wrong login or pass, return */
-    return SEND_REQUIRED_NO;
+		            /* Login and pass are valid */
+
+	            /* TODO replace global flag with user-pass-cookie */
+		        	Authenticated = true;
+		        	break;
+		        }
+		        else{
+		        	Authenticated = false;
+		        }
+		  }
+	  }
+
+	  if(Authenticated){
+		  /* Generate cookie */
+		  sprintf(tempStr, "%X", (unsigned int)GetRandomNumber());
+
+		  /* Set users cookie */
+		  HTTP_SetUserCookie(tempStr, user_id);
+
+		  HTTP_UpdateUserLoginTime(user_id);
+
+		  /* Send login and cookie back */
+		  strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\nSet-Cookie: uname=");
+		  strcat(bufOut, login);
+		  strcat(bufOut, "\r\nSet-Cookie: id=");
+		  strcat(bufOut, tempStr);
+		  sprintf(tempStr, "%d", user_id);
+		  strcat(bufOut, "\r\nSet-Cookie: role=");
+		  strcat(bufOut, tempStr);
+		  if(sSettings.sRADIUS.Auth_enable)
+			strcat(bufOut, "\r\nSet-Cookie: auth=1");
+		else
+			strcat(bufOut, "\r\nSet-Cookie: auth=0");
+		  strcat(bufOut, "\r\n\r\n");
+		  strcat(bufOut,"<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/index.html\"/></head></html>\r\n\r\n");
+
+		  *lenBufOut = strlen(bufOut);
+		  if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false)){
+			  snprintf(name_login, (strlen(login)+1), login);
+		  }
+		  else{
+			  fl_raddius_net_err = false;
+			  switch (user_id) {
+				  case 0:
+					  snprintf(name_login, sizeof(name_login), "Администратор");
+					  break;
+				  case 1:
+					  snprintf(name_login, sizeof(name_login), "Пользователь");
+					  break;
+				  default:
+					  snprintf(name_login, (strlen(login)+1), login);
+					  break;
+			  }
+		  }
+
+
+		  log_event_data(LOG_LOGIN, name_login);
+		  /* Запускаем задачу-таймер логаута. */
+		  /* TODO отправить ответ серверу о статусе пароля */
+		  return SEND_REQUIRED_YES;
+	  }
+	  else{
+		  strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type: text/html;\r\n\r\n");
+		  if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
+			  strcat(bufOut,"<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/rslogin.html\" /></head><center><h2>Не правильный логин или пароль</h2></center></html>");
+		  else
+			  strcat(bufOut,"<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"refresh\" content=\"3; url=/login.html\" /></head><center><h2>Не правильный логин или пароль</h2></center></html>");
+		  *lenBufOut = strlen(bufOut);
+		  return SEND_REQUIRED_NO;
+	  }
 }
 
 void HTTP_LOGIN(char *bufOut, uint16_t *lenBufOut)
@@ -1811,6 +1862,7 @@ void HTTP_LOGIN(char *bufOut, uint16_t *lenBufOut)
 	GetUserLogin(ADMIN, WebLogin, &valueLen);
 
 	memset(tempStr, 0, 50);
+	memset(name_login, 0, 50);
 
 	/* TODO replace global flag with user-pass-cookie */
 	Authenticated = true;
@@ -1837,6 +1889,8 @@ void HTTP_LOGIN(char *bufOut, uint16_t *lenBufOut)
 	strcat(bufOut,"<!DOCTYPE html><html lang=""><head><meta http-equiv=\"refresh\" content=\"0;url=/index.html\"/></head></html>\r\n\r\n");
 
 	*lenBufOut = strlen(bufOut);
+
+	snprintf(name_login, sizeof(name_login), "Администратор");
 }
 
 /**
@@ -2092,7 +2146,7 @@ int HTTP_ChangeUserPwd(char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *l
 					 memcpy(sSettings.sAuth[user_id].password, password, 11);
 
 					 HTTP_SaveSettings();
-					 log_event_data(LOG_PSW_CHANGE, "Администратор");
+					 log_event_data(LOG_PSW_CHANGE, name_login);
 					 strcat(bufOut, "Пароль успешно изменён");
 					 *lenBufOut = strlen(bufOut);
 					 return SEND_REQUIRED_YES;
@@ -2287,6 +2341,45 @@ static int my_set_session(ssl_context *ssl)
   return(0);
 }
 
+void ssl_server_read(void)
+{
+	int ret;
+
+    do
+    {
+        receivedBufLen = RECIVE_BUF_MAX_LEN - 1;
+        memset(receiveBuf, 0, RECIVE_BUF_MAX_LEN);
+
+        // Read decrypted application data
+        ret = ssl_read(&ssl, (unsigned char*)receiveBuf, receivedBufLen);
+
+        if(ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE)
+            continue;
+
+        if(ret <= 0)
+        {
+            switch(ret)
+            {
+            case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
+                printf("\n\r connection was closed \n");
+            break;
+
+            case POLARSSL_ERR_NET_CONN_RESET:
+                printf("\n\r connection was reset by peer\n");
+            break;
+
+            default:
+                //printf("\n\r ssl_read returned %d\n", ret);
+            break;
+            }
+            break;
+        }
+        receivedBufLen = ret;
+        // Display the length of read data
+        //printf("\n\r Successfully read %d bytes from client \n\r",len);
+    }while(0);
+}
+
 /**
   * @brief  SSL Server task.
   * @param  pvParameters not used
@@ -2305,7 +2398,7 @@ void ssl_server(void *pvParameters)
     char name[MAX_WEB_COOKIE_LEN];
     char id[MAX_WEB_COOKIE_LEN];
     uint8_t nameLen = 0, idLen = 0;
-    uint32_t DataOffset;
+    char *DataOffset;
     struct fs_file file = {0, 0};
     uint32_t i;
     
@@ -2415,39 +2508,7 @@ void ssl_server(void *pvParameters)
 
         // 6. Read the HTTP Request 
         //printf("\n\r <= Read from client :");
-        do
-        {
-            receivedBufLen = RECIVE_BUF_MAX_LEN - 1;
-            memset(receiveBuf, 0, RECIVE_BUF_MAX_LEN);
-
-            // Read decrypted application data 
-            ret = ssl_read(&ssl, (unsigned char*)receiveBuf, receivedBufLen);
-
-            if(ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE)
-                continue;
-
-            if(ret <= 0)
-            {
-                switch(ret)
-                {
-                case POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY:
-                    printf("\n\r connection was closed \n");
-                break;
-
-                case POLARSSL_ERR_NET_CONN_RESET:
-                    printf("\n\r connection was reset by peer\n");
-                break;
-
-                default:
-                    //printf("\n\r ssl_read returned %d\n", ret);
-                break;
-                }
-                break;
-            }
-            receivedBufLen = ret;
-            // Display the length of read data 
-            //printf("\n\r Successfully read %d bytes from client \n\r",len);
-        }while(0);
+        ssl_server_read();
 
     // -------------------------------------------------------------------------
         
@@ -2478,7 +2539,6 @@ void ssl_server(void *pvParameters)
         // Id of currently logged-in user 
         uint8_t user_id;
         
-        if( DataFlag == 0 && DataFlag2 == 0) {
         // Level of currently logged-in user 
         seclevel = 0xFF;
         for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
@@ -2491,13 +2551,7 @@ void ssl_server(void *pvParameters)
             Authenticated = false;
             seclevel = 0xFF;
         }
-        }
-        if (DataFlag >= 1)
-            Authenticated = true;
-        else if(DataFlag2 >= 1)
-            Authenticated = true;
 
-       
         if ( Authenticated == false && sSettings.sRADIUS.Auth_enable == false)
         {
             HTTP_LOGIN(sendBuf, &sendBufLoadLen);
@@ -2525,65 +2579,75 @@ void ssl_server(void *pvParameters)
                 fs_open("/role.js", &file);
                 ssl_sendframes(&ssl, file.data, file.len);
             }
-            else if ((strncmp(receiveBuf, "POST /login.cgi", 15) == 0) || (log_post_reqn > 0))
+            else if (strncmp(receiveBuf, "POST /login.cgi", 15) == 0)
             {
-                uint32_t i, offset = 0, req_data_received = 0;
+                uint32_t req_data_received = 0;
+                char *offset;
+
+                offset = 0;
                 
                 post_data_count = Parse_Content_Length(receiveBuf, receivedBufLen);
 			  
                 if (post_data_count < MAX_POST_REQ_LEN) 
                 {
                     memset(post_req_data, 0, MAX_POST_REQ_LEN);
-					
-					for (i = 0; i < receivedBufLen; i++)
-					{
-						if (strncmp ((char*)(receiveBuf+i), "\r\n\r\n", 4) == 0)
-						{
-							offset = i+4;
-							break;
-						}
-					}
 
-					req_data_received = receivedBufLen - offset;
-					
+                    offset = (strstr(receiveBuf, "\r\n\r\n")) + 4;
+                    req_data_received = receivedBufLen - (offset - &receiveBuf[0]);
+
 					if (offset != 0) 
                     {
                         if (req_data_received < post_data_count) 
                         {
                             snprintf(post_req_data, req_data_received, "%s", receiveBuf);
                             post_data_count -= req_data_received;
+
+                            ssl_server_read();
+
+                            offset = receiveBuf;
                         }
-                        else 
+
+                        if(strlen(receiveBuf) != 0)
                         {
-                            strncat(post_req_data, (char *)(receiveBuf + offset), post_data_count);
-						
+
+                            strncat(post_req_data, offset, post_data_count);
                             if (HTTP_ConfirmWebPwd(post_req_data, sendBuf, strlen(post_req_data), &sendBufLoadLen) == SEND_REQUIRED_YES) 
                             {
                                 ssl_sendframes(&ssl, sendBuf, sendBufLoadLen);
                             }
                             else 
                             {
-                                fs_open("/login.html", &file);
-                                ssl_sendframes(&ssl, file.data, file.len);
+                            	/*if(sSettings.sRADIUS.RDSEnable == true)
+                            		fs_open("/rslogin.html", &file);
+                            	else
+                            		fs_open("/login.html", &file);
+                                ssl_sendframes(&ssl, file.data, file.len);*/
+                            	ssl_sendframes(&ssl, sendBuf, sendBufLoadLen);
                             }
                             post_data_count = 0;
-                            log_post_reqn = 0;
+                        }
+                        else{
+    						/* Redirect to login page */
+    						if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
+    							fs_open("/rslogin.html", &file);
+    						else
+    							fs_open("/login.html", &file);
+    						ssl_sendframes(&ssl, file.data, file.len);
+    						/* End reqest */
+    						post_data_count = 0;
                         }
 					}
 					/* request was fragmented before "\r\n\r\n" */
 					else 
                     {
-						log_post_reqn++;
-						/* wait max 2 requests */
-						if (log_post_reqn > 1) 
-                        {
-							/* Redirect to login page */
+						/* Redirect to login page */
+						if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
+							fs_open("/rslogin.html", &file);
+						else
 							fs_open("/login.html", &file);
-                            ssl_sendframes(&ssl, file.data, file.len);
-							/* End reqest */
-							post_data_count = 0;
-							log_post_reqn = 0;
-						}
+						ssl_sendframes(&ssl, file.data, file.len);
+						/* End reqest */
+						post_data_count = 0;
 					}
                 }
                 else 
@@ -2591,10 +2655,12 @@ void ssl_server(void *pvParameters)
                     //printf("Too long POST request!\r\n");
                     /* Ignore request */
                     post_data_count = 0;
-                    log_post_reqn = 0;
 
                     /* Redirect to login page */
-                    fs_open("/login.html", &file);
+                    if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
+						fs_open("/rslogin.html", &file);
+					else
+						fs_open("/login.html", &file);
                     ssl_sendframes(&ssl, file.data, file.len);
                 }
             }
@@ -2608,15 +2674,22 @@ void ssl_server(void *pvParameters)
                 }
 				else 
                 {
-					fs_open("/login.html", &file);
-                    ssl_sendframes(&ssl, file.data, file.len);
+					/*if(sSettings.sRADIUS.RDSEnable == true)
+						fs_open("/rslogin.html", &file);
+					else
+						fs_open("/login.html", &file);
+                    ssl_sendframes(&ssl, file.data, file.len);*/
+					ssl_sendframes(&ssl, sendBuf, sendBufLoadLen);
 				}
                 post_data_count = 0;
 				log_post_reqn = 0;
 			}
             else
             {
-                fs_open("/login.html", &file);
+            	if((sSettings.sRADIUS.RDSEnable == true) && (fl_raddius_net_err == false))
+					fs_open("/rslogin.html", &file);
+				else
+					fs_open("/login.html", &file);
                 ssl_sendframes(&ssl, file.data, file.len);
 			}
         }
@@ -2700,86 +2773,47 @@ void ssl_server(void *pvParameters)
                 {
                     DataOffset = 0;
 
+
                     // POST Packet received 
-                    if (DataFlag2 == 0)
-                    {
-                        BrowserFlag = 0;
-                        TotalReceived = 0;
-                        memset(sendBuf, 0, strlen(sendBuf));
 
-                        // parse packet for Content-length field 
-                        size = Parse_Content_Length(receiveBuf, receivedBufLen);
+					TotalReceived = 0;
+					TotalData = 0;
+					memset(sendBuf, 0, strlen(sendBuf));
 
-                        // parse packet for the octet-stream field 
-                        for (i = 0; i < receivedBufLen; i++)
-                        {
-                            if (strncmp ((char*)(receiveBuf+i), "managerIP", 8)==0)
-                            {
-                                DataOffset = i;
-                                break;
-                            }
-                        }     
-                        /* case of MSIE8 : we do not receive data in the POST packet*/
-                        if (DataOffset == 0)
-                        {
-                            DataFlag2++;
-                            BrowserFlag = 1;
-                            //pbuf_free(p);
-                            return;
-                        }
-                        // case of Mozilla Firefox v3.6 : we receive data in the POST packet
-                        else
-                        {
-                            //TotalReceived = receivedBufLen - (ContentLengthOffset + 4);
-                            TotalReceived = receivedBufLen - DataOffset;
-                        }
-                    }
-                    if (((DataFlag2 ==1)&&(BrowserFlag==1)) || ((DataFlag2 ==0)&&(BrowserFlag==0)))
-                    {
-                        if ((DataFlag2 ==0)&&(BrowserFlag==0))
-                        {
-                            DataFlag2++;
-                        }
-                        else if ((DataFlag2 ==1)&&(BrowserFlag==1))
-                        {
-                        // parse packet for the octet-stream field */
-                            for (i = 0; i < receivedBufLen; i++)
-                            {
-                                if (strncmp ((char*)(receiveBuf+i), "managerIP", 8)==0)
-                                {
-                                    DataOffset = i;
-                                    break;
-                                }
-                            }
-                            TotalReceived += receivedBufLen;
-                            DataFlag2++;
-                        }
-                        TotalData = 0;
-                    }
-                    // DataFlag >1 => the packet is data only  
-                    else
-                    {
-                        TotalReceived +=receivedBufLen;
-                    }
+					// parse packet for Content-length field
+					size = Parse_Content_Length(receiveBuf, receivedBufLen);
+
+					DataOffset = strstr(receiveBuf, "managerIP");
 
-                    ptr = (char*)(receiveBuf + DataOffset);
-                    receivedBufLen-= DataOffset;
+					/* case of MSIE8 : we do not receive data in the POST packet*/
+					if (DataOffset == 0)
+					{
+						ssl_server_read();
+						DataOffset = strstr(receiveBuf, "managerIP");
+					}
+
+					TotalReceived = receivedBufLen - (DataOffset - &receiveBuf[0]);
+
+					TotalData += TotalReceived;
+
+					strncat(sendBuf,  DataOffset, TotalReceived);
 
-                    // update Total data received counter 
-                    TotalData +=receivedBufLen;
+					for(i  = TotalData; i < size; i ++)
+					{
+						ssl_server_read();
+						strncat(sendBuf,  DataOffset, receivedBufLen);
+						TotalData += receivedBufLen;
+					}
 
                     // check if last data packet 
-                    if (TotalReceived == size)
+                    if (TotalData == size)
                     {
-                        //DBG printf("State: Received %d bytes\r\n", (int)TotalReceived);
+                       printf("State: Received %d bytes\r\n", (int)TotalData);
 
-                        strncat(sendBuf,  ptr, receivedBufLen);
+                        printf("receive %s /r/n", sendBuf);
                         strncat(sendBuf,  " ", 1);
-                        //ВBG printf("receive %s /r/n", sendBuf);
                         HTTP_SetSettings(sendBuf, strlen(sendBuf));
 
-                        DataFlag2=0;
-                        BrowserFlag = 0;
                         memset(sendBuf, 0, size);
 
                         strcpy(sendBuf, "HTTP/1.1 200 OK\r\n");
@@ -2789,16 +2823,6 @@ void ssl_server(void *pvParameters)
                         sendBufLoadLen = strlen(sendBuf);
                         ssl_sendframes(&ssl, sendBuf, sendBufLoadLen);
                     }
-                    // not last data packet 
-                    else
-                    {
-                        // write data in flash 
-                        if(receivedBufLen)
-                        {
-                            strncat(sendBuf,  ptr, receivedBufLen);
-                            //memcpy(receiveBufTemp, ptr, receivedBufLen);
-                        }
-                    }
                 }  
             } 
             else if (strncmp(receiveBuf, "GET /info.cgi", 13) == 0) // +
@@ -2812,80 +2836,35 @@ void ssl_server(void *pvParameters)
             {
                 if (seclevel == 0) 
                 {
-                    DataOffset = 0;
+                	 DataOffset = 0;
 
-                    // POST Packet received 
-                    if (DataFlag == 0)
-                    {
-                        BrowserFlag = 0;
-                        TotalReceived = 0;
-                        memset(sendBuf, 0, strlen(sendBuf));
+					// POST Packet received
 
-                        // parse packet for Content-length field 
-                        size = Parse_Content_Length(receiveBuf, receivedBufLen);
+					TotalReceived = 0;
+					TotalData = 0;
+					memset(sendBuf, 0, strlen(sendBuf));
 
-                        // parse packet for the octet-stream field 
-                        for (i = 0; i < receivedBufLen; i++)
-                        {
-                            if (strncmp ((char*)(receiveBuf+i), "owner", 5)==0)
-                            {
-                                DataOffset = i;
-                                break;
-                            }
-                        }
-                        // case of MSIE8 : we do not receive data in the POST packet
-                        if (DataOffset == 0)
-                        {
-                            DataFlag++;
-                            BrowserFlag = 1;
-                            //pbuf_free(p);
-                            return;
-                        }
-                        // case of Mozilla Firefox v3.6 : we receive data in the POST packet*/
-                        else
-                        {
-                            //TotalReceived = receivedBufLen - (ContentLengthOffset + 4);
-                            TotalReceived = receivedBufLen - DataOffset;
-                        }
-                    }
-                    if (((DataFlag ==1)&&(BrowserFlag==1)) || ((DataFlag ==0)&&(BrowserFlag==0)))
-                    {
-                        if ((DataFlag ==0)&&(BrowserFlag==0))
-                        {
-                            DataFlag++;
-                        }
-                        else if ((DataFlag ==1)&&(BrowserFlag==1))
-                        {
-                            // parse packet for the octet-stream field */
-                            for (i = 0; i < receivedBufLen; i++)
-                            {
-                                if (strncmp ((char*)(receiveBuf+i), "owner", 5)==0)
-                                {
-                                    DataOffset = i;
-                                    break;
-                                }
-                            }
-                            TotalReceived += receivedBufLen;
-                            DataFlag++;
-                        }
-                        TotalData =0 ;
-                    }
-                    // DataFlag >1 => the packet is data only  
-                    else
-                    {
-                        TotalReceived +=receivedBufLen;
-                    }
-    
-                    ptr = (char*)(receiveBuf + DataOffset);
-                    receivedBufLen-= DataOffset;
+					// parse packet for Content-length field
+					size = Parse_Content_Length(receiveBuf, receivedBufLen);
+
+					DataOffset = strstr(receiveBuf, "owner");
+
+					/* case of MSIE8 : we do not receive data in the POST packet*/
+					if (DataOffset == 0)
+					{
+						ssl_server_read();
+						DataOffset = strstr(receiveBuf, "owner");
+					}
+
+					TotalReceived = receivedBufLen - (DataOffset - &receiveBuf[0]);
+
+					TotalData += TotalReceived;
 
-                    // update Total data received counter 
-                    TotalData +=receivedBufLen;
+					strncat(sendBuf,  DataOffset, TotalReceived);
 
                     // check if last data packet 
                     if (TotalReceived == size)
                     {
-                        strncat(sendBuf,  ptr, receivedBufLen);
                         strncat(sendBuf,  " ", 1);
                         HTTP_SetInfo(sendBuf, strlen(sendBuf));
                         DataFlag = 0;

+ 3 - 3
modules/HTTP_Server/web_params_api.c

@@ -423,7 +423,7 @@ void HTTP_ResetSettings(void)
   //taskENTER_CRITICAL();
 
   SNMP_SendUserTrap(DEVICE_RESTORED);
-  log_event_data(LOG_SYSTEM_DEFCONFIG, "Администратор");
+  log_event_data(LOG_SYSTEM_DEFCONFIG, name_login);
   vTaskDelay(500);
   SETTINGS_SetPartDefault();
   SETTINGS_Save();
@@ -440,7 +440,7 @@ void HTTP_SaveSettings(void)
   
   SETTINGS_Save();
   
-  log_event_data(LOG_SETTING_SAVE, "Администратор");
+  log_event_data(LOG_SETTING_SAVE, name_login);
 
 //  taskEXIT_CRITICAL();
 
@@ -486,7 +486,7 @@ void vTaskReboot(void * pvParameters)
 	if (mode)
 	{
 	  SNMP_SendUserTrap(FW_VERSION_UPDATE);
-	  log_event_data(LOG_UPDATE_SOFT, "Администратор");
+	  log_event_data(LOG_UPDATE_SOFT, name_login);
 	  SetLoadMode();
 	  HTTP_SaveSettings();
       vTaskDelay(2000);

+ 10 - 0
modules/Makefile

@@ -45,6 +45,7 @@ INCLUDES += -Icommon
 INCLUDES += -Imonitor
 INCLUDES += -Ilog
 INCLUDES += -Itesting
+INCLUDES += -Iradius
 CSRC += $(wildcard leds/*.c)
 CSRC += $(wildcard buttons/*.c)
 CSRC += $(wildcard jumper/*.c)
@@ -54,6 +55,7 @@ CSRC += $(wildcard common/*.c)
 CSRC += $(wildcard monitor/*.c)
 CSRC += $(wildcard log/*.c)
 CSRC += $(wildcard testing/*.c)
+CSRC += $(wildcard radius/*.c)
 
 CFLAGS += -DOS_FREERTOS
 CFLAGS += -DHARDWARE_$(shell echo $(HARDWARE) | tr a-z A-Z)
@@ -104,6 +106,14 @@ INCLUDES += -I../thirdparty/PolarSSL/include/polarssl/
 INCLUDES += -I../thirdparty/PolarSSL/include/
 
 CSRC += $(wildcard ../thirdparty/PolarSSL/library/*.c)
+
+#RADDIUS_SERVER
+
+INCLUDES += -I../thirdparty/FreeRadius/
+INCLUDES += -I../thirdparty/FreeRadius/include/
+INCLUDES += -I../thirdparty/FreeRadius/lib/
+
+CSRC += $(wildcard ../thirdparty/FreeRadius/lib/*.c)
     
     
 CFLAGS += -DUSE_STDPERIPH_DRIVER -DSTM32F40_41xxx -DLOG_ENABLE

+ 1 - 1
modules/common/hal.c

@@ -19,7 +19,7 @@
 void Reboot(void) {
 #ifndef BT6702_SERVICE
 	SNMP_SendUserTrap(DEVICE_REBOOTED);
-	log_event_data(LOG_SYSTEM_BOOT, "Администратор");
+	log_event_data(LOG_SYSTEM_BOOT, name_login);
 
 	vTaskDelay(1010);
 	LOG_Disable();

+ 2 - 0
modules/log/log.c

@@ -11,6 +11,8 @@
 
 char logFileBuf[FILE_BUF_MAX_LEN];
 
+char name_login[50];
+
 const char* logsStrShortRu[] =
 {
 	"Перезагрузка контроллера",

+ 2 - 0
modules/log/log.h

@@ -10,6 +10,8 @@
 
 extern char logFileBuf[FILE_BUF_MAX_LEN];
 
+extern char name_login[50];
+
 typedef __packed enum {
 	LOG_SYSTEM_BOOT = 0x00,			// device booted
 	LOG_SYSTEM_DEFCONFIG,	// default config applied

+ 326 - 0
modules/radius/radius_user.c

@@ -0,0 +1,326 @@
+/********************************* (C) РОТЕК ***********************************
+ * @module  template
+ * @file    template.c
+ * @version 1.0.0
+ * @date    XX.XX.XXXX
+ * $brief   template
+ *******************************************************************************
+ * @history     Version  Author         Comment
+ * XX.XX.XXXX   1.0.0    Telenkov D.A.  First release.
+ *******************************************************************************
+ */
+
+#include "stm32f4xx.h"  
+#include "radius_user.h"
+
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "freeradius-client.h"
+#include "fr_options.h"
+
+rc_handle	rcHandle;
+
+int auth_order = AUTH_LOCAL_SND;
+int login_tries = 4;
+int login_timeout = 60;
+char* nologin = "?";
+char* issue = "?";
+char* authserver = "192.168.1.2:1645";
+char* acctserver = "0";
+char* servers = "?";
+char* dictionary = "?";
+char *login_radius = "?";
+char *mapfile = "?";
+char *default_realm = NULL;
+int radius_timeout = 10;
+int radius_retries = 3;
+int radius_deadtime = 0;
+char *bindaddr = "*";
+char *login_local = "?";
+
+OPTION      rcOptions[] = {
+{"auth_order",	 	OT_AUO, ST_UNDEF, (void*)&auth_order}, // AUTH_LOCAL_FST AUTH_RADIUS_FST AUTH_LOCAL_SND AUTH_RADIUS_SND
+{"login_tries",	 	OT_INT, ST_UNDEF, (void*)&login_tries},
+{"login_timeout",	OT_INT, ST_UNDEF, (void*)&login_timeout},
+{"nologin",		    OT_STR, ST_UNDEF, NULL},
+{"issue",		    OT_STR, ST_UNDEF, NULL},
+// RADIUS specific options 
+{"authserver",		OT_SRV, ST_UNDEF, (void*)&authserver},
+{"acctserver",		OT_SRV, ST_UNDEF, (void*)&acctserver},
+{"servers",		    OT_STR, ST_UNDEF, (void*)&servers},
+{"dictionary",		OT_STR, ST_UNDEF, (void*)&dictionary},
+{"login_radius",	OT_STR, ST_UNDEF, (void*)&login_radius},
+{"mapfile",		    OT_STR, ST_UNDEF, (void*)&mapfile},
+{"default_realm",	OT_STR, ST_UNDEF, (void*)&default_realm},
+{"radius_timeout",	OT_INT, ST_UNDEF, (void*)&radius_timeout},
+{"radius_retries",	OT_INT,	ST_UNDEF, (void*)&radius_retries},
+{"radius_deadtime",	OT_INT, ST_UNDEF, (void*)&radius_deadtime},
+{"bindaddr",		OT_STR, ST_UNDEF, (void*)&bindaddr},
+// local options 
+{"login_local",		OT_STR, ST_UNDEF, (void*)&login_local},
+};
+
+static DICT_ATTR   attr_1;
+static DICT_ATTR   attr_2;
+static DICT_ATTR   attr_3;
+
+static char rc_msg[PW_MAX_MSG_SIZE];
+
+
+RadiusClientResult RC_Login(char* login, char* pas)
+{
+    VALUE_PAIR* send;
+    VALUE_PAIR* received;
+    uint32_t	service;
+    
+    int result;
+    
+    memset(rc_msg, 0, PW_MAX_MSG_SIZE);
+
+    memset(&rcHandle, 0, sizeof(rc_handle));
+  
+    rc_read_config(&rcHandle);
+    
+    // Формирование атрибутов
+    // 1. User name
+    strncpy(attr_1.name, login, strlen(login));
+    attr_1.value = 1;
+    attr_1.type = PW_TYPE_STRING;
+    attr_1.next = NULL;
+    
+    // 2. Password
+    strncpy(attr_2.name, pas, strlen(pas));
+    attr_2.value = 2;
+    attr_2.type = PW_TYPE_STRING;
+    attr_2.next = &attr_1;
+    
+    // 3. Service type
+    strcpy(attr_3.name, "Service-Type");
+    attr_3.value = 6;
+    attr_3.type = PW_TYPE_INTEGER;
+    attr_3.next = &attr_2;
+    
+    rcHandle.dictionary_attributes = &attr_3;
+    
+    send = NULL;
+    
+	// User-Name
+    if (rc_avpair_add(&rcHandle, &send, PW_USER_NAME, login, -1, 0) == NULL)
+		return RC_ERROR;
+    
+	// User-Password
+	if (rc_avpair_add(&rcHandle, &send, PW_USER_PASSWORD, pas, -1, 0) == NULL)
+		return RC_ERROR;
+	
+	// Service-Type
+	service = PW_AUTHENTICATE_ONLY;
+	if (rc_avpair_add(&rcHandle, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL)
+		return RC_ERROR;
+
+    result = rc_auth(&rcHandle, 0, send, &received, rc_msg);
+    
+    switch (result)
+    {
+    case USER_RC :
+        return RC_LOGIN_USER_OK;
+    break;
+    
+    case ADMIN_RC :
+        return RC_LOGIN_ADMIN_OK;
+    break;
+    
+    case NET_ERR_RC :
+        return RC_NET_ERR;
+    break;
+    
+    case ERROR_RC :
+        return RC_ERROR;
+    break;
+    
+    case BADRESP_RC :
+        return RC_ACC_DENIED;
+    break;
+    
+    case REJECT_RC :
+        return RC_ACC_DENIED;
+    break;
+    
+    default :
+        return RC_ERROR;
+    break;
+    }
+    return RC_ERROR;
+    //printf("\r\n");
+    //printf("Radius client result: %i\r\n", result);
+    
+}
+
+/**
+  * @brief  
+  */
+int RD_TestInit(void)
+{
+    int         result;
+	char		username[128];
+	char        passwd[AUTH_PASS_LEN + 1];
+	VALUE_PAIR 	*send, *received;
+	uint32_t	service;
+	char 		msg[PW_MAX_MSG_SIZE], username_realm[256];
+	char		*default_realm;
+	  
+    // Моя подготовка 
+    memset(username, 0, 128);
+    memset(passwd, 0, AUTH_PASS_LEN + 1);
+    memset(msg, 0, PW_MAX_MSG_SIZE);
+    memset(username_realm, 0, 256);
+    
+    
+    // Просто копируем структуру настроек которая жесто задана
+    rc_read_config(&rcHandle);
+   
+    // Словарь пока опускаем и не инициализируем
+    //if (rc_read_dictionary(&rcHandle, rc_conf_str(&rcHandle, "dictionary")) != 0)
+	//	return ERROR_RC;
+  
+    // Заполняем словарь
+    // 1. User name
+    strcpy(attr_1.name, "test1");
+    attr_1.value = 1;
+    attr_1.type = PW_TYPE_STRING;
+    attr_1.next = NULL;
+    
+    // 2. Password
+    strcpy(attr_2.name, "12345");
+    attr_2.value = 2;
+    attr_2.type = PW_TYPE_STRING;
+    attr_2.next = &attr_1;
+    
+    // 3. Service type
+    strcpy(attr_3.name, "Service-Type");
+    attr_3.value = 6;
+    attr_3.type = PW_TYPE_INTEGER;
+    attr_3.next = &attr_2;
+    
+/*    
+    attr_3.value = 244;
+    attr_3.type = PW_TYPE_STRING;
+    attr_3.next = &attr_2;
+*/    
+    rcHandle.dictionary_attributes = &attr_3;
+    
+    // Не понял что за параметра, пока NULL
+    //default_realm = rc_conf_str(rh, "default_realm");
+    default_realm = NULL;
+
+    // Рараметры ожидаются от пользователя
+    //strncpy(username, "dtelenkov", 9);
+    strncpy(username, "test1", 5);
+    strncpy(passwd, "12345", 5);
+    //strncpy(username, rc_getstr (rh, "login: ",1), sizeof(username));
+	//strncpy (passwd, rc_getstr(rh, "Password: ",0), sizeof (passwd));
+    
+    send = NULL;
+        
+    /*
+	 * Fill in User-Name
+	 */
+
+	strncpy(username_realm, username, sizeof(username_realm));
+
+	/* Append default realm */
+    /*
+	if ((strchr(username_realm, '@') == NULL) && default_realm &&
+	    (*default_realm != '\0'))
+	{
+		strncat(username_realm, "@", sizeof(username_realm)-strlen(username_realm)-1);
+		strncat(username_realm, default_realm, sizeof(username_realm)-strlen(username_realm)-1);
+	}
+    */
+    
+	if (rc_avpair_add(&rcHandle, &send, PW_USER_NAME, username_realm, -1, 0) == NULL)
+		return ERROR_RC;
+    
+	/*
+	 * Fill in User-Password
+	 */
+	if (rc_avpair_add(&rcHandle, &send, PW_USER_PASSWORD, passwd, -1, 0) == NULL)
+		return ERROR_RC;
+
+	/*
+	 * Fill in Service-Type
+	 */
+	service = PW_AUTHENTICATE_ONLY;
+	if (rc_avpair_add(&rcHandle, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL)
+		return ERROR_RC;
+#if 0
+	result = rc_auth(&rcHandle, 0, send, &received, msg);
+
+	if (result == OK_RC)
+	{
+		fprintf(stderr, "\"%s\" RADIUS Authentication OK\n", username);
+	}
+	else
+	{
+		fprintf(stderr, "\"%s\" RADIUS Authentication failure (RC=%i)\n", username, result);
+	}
+
+	
+#endif
+	send = NULL;
+    
+    return 0;
+}
+
+void initFdsets(fdsets *sets)
+{
+    memset((sets)->buf1, 0xab, 8); 
+    memset((sets)->buf2, 0xab, 8); 
+    memset((sets)->buf3, 0xab, 8); 
+    memset((sets)->buf4, 0xab, 8); 
+}
+
+bool recvSelect(fdsets *sets, int *socket, uint32_t timeout)
+{
+    struct timeval tv;
+
+    tv.tv_sec = 0;
+    tv.tv_usec = timeout * 1000;
+      
+    FD_ZERO(&(sets->readset));
+    FD_SET(*socket, &sets->readset);
+    FD_ZERO(&sets->errset);
+    FD_SET(*socket, &sets->errset);
+        
+    lwip_select(*socket + 1, &sets->readset, NULL, &sets->errset, &tv);
+        
+    if (FD_ISSET(*socket, &sets->readset)) 
+        return true;
+
+    return false;
+}
+
+//
+int RC_GetAccessRights(char* buf)
+{
+    uint16_t tmpLen = 0;
+    uint8_t att = 10;
+    
+    while (att)
+    {
+        att--;  // Предохранитель
+        
+        if (strstr(buf, "user") != 0) {
+            return USER_RC; }
+        else if (strstr(buf, "admin") != 0) {
+            return ADMIN_RC; }
+        
+        tmpLen = strlen(buf);
+        buf += tmpLen + 1;            
+    }
+    
+    return ERROR_RC;
+}
+
+
+/********************************* (C) РОТЕК **********************************/

+ 59 - 0
modules/radius/radius_user.h

@@ -0,0 +1,59 @@
+/******************************* (C) LiteMesh **********************************
+ * @module  template
+ * @file    template.h
+ * @version 1.0.0
+ * @date    XX.XX.XXXX
+ * $brief   template
+ *******************************************************************************
+ * @history     Version  Author         Comment
+ * XX.XX.XXXX   1.0.0    Telenkov D.A.  First release.
+ *******************************************************************************
+ */
+
+/* Define to prevent recursive  ----------------------------------------------*/
+#ifndef __RADIUS_USER_H
+#define __RADIUS_USER_H
+
+#include "lwip/sockets.h"
+#include <stdbool.h>
+
+typedef enum
+{
+    RC_ERROR = 0,       // Внутренняя ошибка FreeRadius. 
+    RC_LOGIN_ADMIN_OK,  // Успешный логин под admin
+    RC_LOGIN_USER_OK,   // Успешный логин под user
+    RC_NET_ERR,         // Ошибка сетевого взаимодействия
+    RC_ACC_DENIED,      // Не удалось залогиниться, доступ закрыт
+    
+} RadiusClientResult;
+
+
+typedef struct 
+{
+    u8_t   buf1[8];
+    fd_set readset;
+    u8_t   buf2[8];
+    fd_set writeset;
+    u8_t   buf3[8];
+    fd_set errset;
+    u8_t   buf4[8];
+  
+} fdsets;
+
+RadiusClientResult RC_Login(char* login, char* pas);
+
+/**
+  * @brief  
+  */
+int RD_TestInit(void);
+
+
+void initFdsets(fdsets *sets);
+
+bool recvSelect(fdsets *sets, int *socket, uint32_t timeout);
+
+int RC_GetAccessRights(char* buf);
+
+#endif /* #ifndef __RADIUS_USER_H */
+
+/****************************** (C) LiteMesh ***************** end of file ****/

+ 3 - 2
modules/settings_api.c

@@ -22,6 +22,7 @@
 
 #include "FreeRTOS.h"
 #include "task.h"
+#include "main.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -32,7 +33,7 @@
 #include "tinystdio.h"
 #endif
 
-#define DBG if(0)
+//#define DBG if(0)
 
 #if defined ( __ICCARM__ )
 #define DEVICE_MAC "00-00-00-00-00-03"
@@ -188,7 +189,7 @@ void SETTINGS_SetRADIUSDef(void)
   strcpy(sSettings.sRADIUS.ServerIP, "0.0.0.0");
   sSettings.sRADIUS.port = 1812;
   sSettings.sRADIUS.key_access = 123;
-  strcpy(sSettings.sRADIUS.rds_password, "12345");
+  strcpy(sSettings.sRADIUS.rds_password, "R04ekR4MP2");
 }
   
 /**

+ 12 - 0
peripheral_modules/src/usart.c

@@ -26,6 +26,18 @@
 #include "tinystdio.h"
 #endif
 
+#ifdef __ICCARM__
+  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)    
+
+
+PUTCHAR_PROTOTYPE   
+{   
+  USART_SendData(USER_USART, (u8) ch);   
+  while(USART_GetFlagStatus(USER_USART, USART_FLAG_TXE) == RESET) {}   
+  return ch;   
+}   
+#endif
+
 #ifdef BT6702_SERVICE
 #define UPS_RBUF_SIZE 1024
 #else

+ 53 - 0
projects/iar/bt-670x.ewp

@@ -335,6 +335,8 @@
           <state>$PROJ_DIR$\..\..\modules\jumper</state>
           <state>$PROJ_DIR$\..\..\modules\STM32F4x7_ETH_Driver</state>
           <state>$PROJ_DIR$\..\..\modules\log</state>
+          <state>$PROJ_DIR$\..\..\modules\testing</state>
+          <state>$PROJ_DIR$\..\..\modules\radius</state>
           <state>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\include</state>
           <state>$PROJ_DIR$\..\..\thirdparty\FreeRTOS\portable\IAR\ARM_CM4F</state>
           <state>$PROJ_DIR$\..\..\thirdparty\lwip\src\include</state>
@@ -345,6 +347,9 @@
           <state>$PROJ_DIR$\..\..\thirdparty\lwip\arch</state>
           <state>$PROJ_DIR$\..\..\thirdparty\PolarSSL\include\polarssl</state>
           <state>$PROJ_DIR$\..\..\thirdparty\PolarSSL\include</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\FreeRadius</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\FreeRadius\include</state>
+          <state>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib</state>
         </option>
         <option>
           <name>CCStdIncCheck</name>
@@ -2055,6 +2060,12 @@
         <name>$PROJ_DIR$\..\..\modules\monitor\ups_monitor.c</name>
       </file>
     </group>
+    <group>
+      <name>radius</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\radius\radius_user.c</name>
+      </file>
+    </group>
     <group>
       <name>STM32F4x7_ETH_Driver</name>
       <file>
@@ -2064,6 +2075,12 @@
         <name>$PROJ_DIR$\..\..\modules\STM32F4x7_ETH_Driver\stm32f4x7_eth_bsp.c</name>
       </file>
     </group>
+    <group>
+      <name>testing</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\modules\testing\testing.c</name>
+      </file>
+    </group>
     <file>
       <name>$PROJ_DIR$\..\..\modules\parameters.c</name>
     </file>
@@ -2217,6 +2234,42 @@
   </group>
   <group>
     <name>thirdparty</name>
+    <group>
+      <name>freeradius</name>
+      <group>
+        <name>lib</name>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\avpair.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\buildreq.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\config.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\dict.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\fr_log.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\fr_md5.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\fr_options.h</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\rc-md5.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\sendserver.c</name>
+        </file>
+        <file>
+          <name>$PROJ_DIR$\..\..\thirdparty\FreeRadius\lib\util.c</name>
+        </file>
+      </group>
+    </group>
     <group>
       <name>freertos</name>
       <group>

+ 564 - 0
thirdparty/FreeRadius/include/freeradius-client.h

@@ -0,0 +1,564 @@
+/*
+ * $Id: freeradius-client.h,v 1.18 2010/06/15 09:22:51 aland Exp $
+ *
+ * Copyright (C) 1995,1996,1997,1998 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#ifndef FREERADIUS_CLIENT_H
+#define FREERADIUS_CLIENT_H
+
+//#define CP_DEBUG
+
+#ifdef CP_DEBUG
+#define		DEBUG(args, ...)	rc_log(## args)
+#else
+#define		DEBUG(args, ...)	;
+#endif
+
+//#include	<sys/types.h>
+#include "radius_config.h"
+/*
+ * Include for C99 uintX_t defines is stdint.h on most systems.  Solaris uses
+ * inttypes.h instead.  Comment out the stdint include if you get an error,
+ * and uncomment the inttypes.h include.
+ */
+#include	<stdint.h>
+/* #include	<inttypes.h> */
+#ifdef PRINTF_STDLIB
+#include <stdio.h>
+#endif
+#ifdef PRINTF_CUSTOM
+#include "tinystdio.h"
+#endif
+#include	<time.h>
+
+
+/* for struct addrinfo and sockaddr_storage */
+//#include <sys/socket.h>
+#include <netdb.h>
+
+#undef __BEGIN_DECLS
+#undef __END_DECLS
+#ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+#else
+# define __BEGIN_DECLS /* empty */
+# define __END_DECLS /* empty */
+#endif
+
+#define AUTH_VECTOR_LEN		16
+#define AUTH_PASS_LEN		(3 * 16) /* multiple of 16 */
+#define AUTH_ID_LEN		    64
+#define AUTH_STRING_LEN		253	 /* maximum of 253 */
+
+#define BUFFER_LEN		    8192
+
+#define NAME_LENGTH		    32
+#define GETSTR_LENGTH		128	//!< must be bigger than AUTH_PASS_LEN.
+
+#define MAX_SECRET_LENGTH	(3 * 16) /* MUST be multiple of 16 */
+
+#define VENDOR(x)		(((x) >> 16) & 0xffff)
+#define ATTRID(x)		((x) & 0xffff)
+
+#define PW_MAX_MSG_SIZE		256//4096
+
+   
+/* codes for radius_buildreq, radius_getport, etc. */
+#define AUTH			0
+#define ACCT			1
+
+/* defines for config.c */
+
+#define SERVER_MAX 8
+
+#define AUTH_LOCAL_FST	(1<<0)
+#define AUTH_RADIUS_FST	(1<<1)
+#define AUTH_LOCAL_SND	(1<<2)
+#define AUTH_RADIUS_SND	(1<<3)
+
+typedef struct server {
+	int max;
+	char *name[SERVER_MAX];
+	uint16_t port[SERVER_MAX];
+	char *secret[SERVER_MAX];
+	double deadtime_ends[SERVER_MAX];
+} SERVER;
+
+typedef struct pw_auth_hdr
+{
+	uint8_t		code;
+	uint8_t		id;
+	uint16_t	length;
+	uint8_t		vector[AUTH_VECTOR_LEN];
+	uint8_t		data[2];
+} AUTH_HDR;
+
+struct rc_conf
+{
+	struct _option		    *config_options;
+	struct sockaddr_storage	own_bind_addr;
+	unsigned		        own_bind_addr_set;
+
+	struct map2id_s		    *map2id_list;
+	struct dict_attr	    *dictionary_attributes;
+	struct dict_value	    *dictionary_values;
+	struct dict_vendor	    *dictionary_vendors;
+	char			        buf[GETSTR_LENGTH];
+    char    			    buf1[14];
+	char	    		    ifname[512];
+};
+
+typedef struct rc_conf rc_handle;
+
+#define AUTH_HDR_LEN			20
+#define CHAP_VALUE_LENGTH		16
+
+#define PW_AUTH_UDP_PORT		1645
+#define PW_ACCT_UDP_PORT		1646
+
+#define PW_TYPE_STRING			0
+#define PW_TYPE_INTEGER			1
+#define PW_TYPE_IPADDR			2
+#define PW_TYPE_DATE			3
+#define PW_TYPE_IPV6ADDR		4
+#define PW_TYPE_IPV6PREFIX		5
+
+/* standard RADIUS codes */
+
+#define PW_ACCESS_REQUEST		1
+#define PW_ACCESS_ACCEPT		2
+#define PW_ACCESS_REJECT		3
+#define PW_ACCOUNTING_REQUEST	4
+#define PW_ACCOUNTING_RESPONSE	5
+#define PW_ACCOUNTING_STATUS	6
+#define PW_PASSWORD_REQUEST		7
+#define PW_PASSWORD_ACK			8
+#define PW_PASSWORD_REJECT		9
+#define PW_ACCOUNTING_MESSAGE	10
+#define PW_ACCESS_CHALLENGE		11
+#define PW_STATUS_SERVER		12
+#define PW_STATUS_CLIENT		13
+
+
+/* standard RADIUS attribute-value pairs */
+
+#define PW_ACCESS               244
+
+#define PW_USER_NAME			1	//!< string.
+#define PW_USER_PASSWORD		2	//!< string.
+#define PW_CHAP_PASSWORD		3	//!< string.
+#define PW_NAS_IP_ADDRESS		4	//!< ipaddr.
+#define PW_NAS_PORT			    5	//!< integer.
+#define PW_SERVICE_TYPE			6	//!< integer.
+#define PW_FRAMED_PROTOCOL		7	//!< integer.
+#define PW_FRAMED_IP_ADDRESS	8	//!< ipaddr.
+#define PW_FRAMED_IP_NETMASK	9	//!< ipaddr.
+#define PW_FRAMED_ROUTING		10	//!< integer.
+#define PW_FILTER_ID			11	//!< string.
+#define PW_FRAMED_MTU			12	//!< integer.
+#define PW_FRAMED_COMPRESSION	13	//!< integer.
+#define PW_LOGIN_IP_HOST		14	//!< ipaddr.
+#define PW_LOGIN_SERVICE		15	//!< integer.
+#define PW_LOGIN_PORT			16	//!< integer.
+#define PW_OLD_PASSWORD			17	//!< string */ /* deprecated.
+#define PW_REPLY_MESSAGE		18	//!< string.
+#define PW_LOGIN_CALLBACK_NUMBER    19	//!< string.
+#define PW_FRAMED_CALLBACK_ID		20	//!< string.
+#define PW_EXPIRATION			21	//!< date */ /* deprecated.
+#define PW_FRAMED_ROUTE			22	//!< string.
+#define PW_FRAMED_IPX_NETWORK	23	//!< integer.
+#define PW_STATE			    24	//!< string.
+#define PW_CLASS			    25	//!< string.
+#define PW_VENDOR_SPECIFIC	    26	//!< string.
+#define PW_SESSION_TIMEOUT		27	//!< integer.
+#define PW_IDLE_TIMEOUT			28	//!< integer.
+#define PW_TERMINATION_ACTION	29	//!< integer.
+#define PW_CALLED_STATION_ID	30	//!< string.
+#define PW_CALLING_STATION_ID	31	//!< string.
+#define PW_NAS_IDENTIFIER		32	//!< string.
+#define PW_PROXY_STATE			33	//!< string.
+#define PW_LOGIN_LAT_SERVICE	34	//!< string.
+#define PW_LOGIN_LAT_NODE		35	//!< string.
+#define PW_LOGIN_LAT_GROUP		36	//!< string.
+#define PW_FRAMED_APPLETALK_LINK	37	//!< integer.
+#define PW_FRAMED_APPLETALK_NETWORK	38	//!< integer.
+#define PW_FRAMED_APPLETALK_ZONE	39	//!< string.
+#define PW_ACCT_STATUS_TYPE		    40	//!< integer.
+#define PW_ACCT_DELAY_TIME		    41	//!< integer.
+#define PW_ACCT_INPUT_OCTETS		42	//!< integer.
+#define PW_ACCT_OUTPUT_OCTETS		43	//!< integer.
+#define PW_ACCT_SESSION_ID		    44	//!< string.
+#define PW_ACCT_AUTHENTIC		    45	//!< integer.
+#define PW_ACCT_SESSION_TIME		46	//!< integer.
+#define PW_ACCT_INPUT_PACKETS		47	//!< integer.
+#define PW_ACCT_OUTPUT_PACKETS		48	//!< integer.
+#define PW_ACCT_TERMINATE_CAUSE		49	//!< integer.
+#define PW_ACCT_MULTI_SESSION_ID	50	//!< string.
+#define PW_ACCT_LINK_COUNT		    51	//!< integer.
+#define PW_ACCT_INPUT_GIGAWORDS		52	//!< integer.
+#define PW_ACCT_OUTPUT_GIGAWORDS	53	//!< integer.
+#define PW_EVENT_TIMESTAMP		    55	//!< integer.
+#define PW_EGRESS_VLANID		    56	//!< string.
+#define PW_INGRESS_FILTERS		    57	//!< integer.
+#define PW_EGRESS_VLAN_NAME		    58	//!< string.
+#define PW_USER_PRIORITY_TABLE		59	//!< string.
+#define PW_CHAP_CHALLENGE		    60	//!< string.
+#define PW_NAS_PORT_TYPE		    61	//!< integer.
+#define PW_PORT_LIMIT			    62	//!< integer.
+#define PW_LOGIN_LAT_PORT		    63	//!< string.
+#define PW_TUNNEL_TYPE			    64	//!< string.
+#define PW_TUNNEL_MEDIUM_TYPE		65	//!< integer.
+#define PW_TUNNEL_CLIENT_ENDPOINT	66	//!< string.
+#define PW_TUNNEL_SERVER_ENDPOINT	67	//!< string.
+#define PW_ACCT_TUNNEL_CONNECTION	68	//!< string.
+#define PW_TUNNEL_PASSWORD		    69	//!< string.
+#define PW_ARAP_PASSWORD		    70	//!< string.
+#define PW_ARAP_FEATURES		    71	//!< string.
+#define PW_ARAP_ZONE_ACCESS		    72	//!< integer.
+#define PW_ARAP_SECURITY		    73	//!< integer.
+#define PW_ARAP_SECURITY_DATA		74	//!< string.
+#define PW_PASSWORD_RETRY		    75	//!< integer.
+#define PW_PROMPT			        76	//!< integer.
+#define PW_CONNECT_INFO			    77	//!< string.
+#define PW_CONFIGURATION_TOKEN		78	//!< string.
+#define PW_EAP_MESSAGE			    79	//!< string.
+#define PW_MESSAGE_AUTHENTICATOR	80	//!< string.
+#define PW_TUNNEL_PRIVATE_GROUP_ID	81	//!< string.
+#define PW_TUNNEL_ASSIGNMENT_ID		82	//!< string.
+#define PW_TUNNEL_PREFERENCE		83	//!< string.
+#define PW_ARAP_CHALLENGE_RESPONSE	84	//!< string.
+#define PW_ACCT_INTERIM_INTERVAL	85	//!< integer.
+#define PW_ACCT_TUNNEL_PACKETS_LOST	86	//!< integer.
+#define PW_NAS_PORT_ID_STRING		87	//!< string.
+#define PW_FRAMED_POOL			    88	//!< string.
+#define PW_CHARGEABLE_USER_IDENTITY	89	//!< string.
+#define PW_CUI				        89	//!< string.
+#define PW_TUNNEL_CLIENT_AUTH_ID	90	//!< string.
+#define PW_TUNNEL_SERVER_AUTH_ID	91	//!< string.
+#define PW_NAS_FILTER_RULE		    92	//!< string.
+#define PW_ORIGINATING_LINE_INFO	94	//!< string.
+#define PW_NAS_IPV6_ADDRESS		    95	//!< string.
+#define PW_FRAMED_INTERFACE_ID		96	//!< string.
+#define PW_FRAMED_IPV6_PREFIX		97	//!< string.
+#define PW_LOGIN_IPV6_HOST		    98	//!< string.
+#define PW_FRAMED_IPV6_ROUTE		99	//!< string.
+#define PW_FRAMED_IPV6_POOL		    100	//!< string.
+#define PW_ERROR_CAUSE			    101	//!< integer.
+#define PW_EAP_KEY_NAME			    102	//!< string.
+
+#define PW_FRAMED_IPV6_ADDRESS		168	//!< ipaddr6.
+#define PW_DNS_SERVER_IPV6_ADDRESS	169	//!< ipaddr6.
+#define PW_ROUTE_IPV6_INFORMATION	170	//!< ipv6prefix.
+
+/* Experimental SIP-specific attributes (draft-sterman-aaa-sip-00.txt etc) */
+
+#define PW_DIGEST_RESPONSE		    206	//!< string.
+#define PW_DIGEST_ATTRIBUTES		207	//!< string.
+#define PW_DIGEST_REALM			    1063	//!< string.
+#define PW_DIGEST_NONCE			    1064	//!< string.
+#define PW_DIGEST_METHOD		    1065	//!< string.
+#define PW_DIGEST_URI			    1066	//!< string.
+#define PW_DIGEST_QOP			    1067	//!< string.
+#define PW_DIGEST_ALGORITHM		    1068	//!< string.
+#define PW_DIGEST_BODY_DIGEST		1069	//!< string.
+#define PW_DIGEST_CNONCE		    1070	//!< string.
+#define PW_DIGEST_NONCE_COUNT		1071	//!< string.
+#define PW_DIGEST_USER_NAME		    1072	//!< string.
+
+/* Integer Translations */
+
+/* SERVICE TYPES */
+
+#define PW_LOGIN			    1
+#define PW_FRAMED			    2
+#define PW_CALLBACK_LOGIN		3
+#define PW_CALLBACK_FRAMED		4
+#define PW_OUTBOUND			    5
+#define PW_ADMINISTRATIVE		6
+#define PW_NAS_PROMPT			7
+#define PW_AUTHENTICATE_ONLY	8
+#define PW_CALLBACK_NAS_PROMPT	9
+
+/* FRAMED PROTOCOLS */
+
+#define PW_PPP				1
+#define PW_SLIP				2
+#define PW_ARA				3
+#define PW_GANDALF			4
+#define PW_XYLOGICS			5
+
+/* FRAMED ROUTING VALUES */
+
+#define PW_NONE				0
+#define PW_BROADCAST		1
+#define PW_LISTEN			2
+#define PW_BROADCAST_LISTEN	3
+
+/* FRAMED COMPRESSION TYPES */
+
+#define PW_VAN_JACOBSON_TCP_IP		1
+#define PW_IPX_HEADER_COMPRESSION	2
+
+/* LOGIN SERVICES */
+
+#define PW_TELNET			0
+#define PW_RLOGIN			1
+#define PW_TCP_CLEAR		2
+#define PW_PORTMASTER		3
+#define PW_LAT				4
+#define PW_X25_PAD			5
+#define PW_X25_T3POS		6
+
+/* TERMINATION ACTIONS */
+
+#define PW_DEFAULT			0
+#define PW_RADIUS_REQUEST	1
+
+/* PROHIBIT PROTOCOL */
+
+#define PW_DUMB			    0	//!< 1 and 2 are defined in FRAMED PROTOCOLS.
+#define PW_AUTH_ONLY	    3
+#define PW_ALL			    255
+
+/* ACCOUNTING STATUS TYPES */
+
+#define PW_STATUS_START		1
+#define PW_STATUS_STOP		2
+#define PW_STATUS_ALIVE		3
+#define PW_STATUS_MODEM_START	4
+#define PW_STATUS_MODEM_STOP	5
+#define PW_STATUS_CANCEL	6
+#define PW_ACCOUNTING_ON	7
+#define PW_ACCOUNTING_OFF	8
+
+/* ACCOUNTING TERMINATION CAUSES */
+
+#define PW_USER_REQUEST		1
+#define PW_LOST_CARRIER		2
+#define PW_LOST_SERVICE		3
+#define PW_ACCT_IDLE_TIMEOUT	4
+#define PW_ACCT_SESSION_TIMEOUT	5
+#define PW_ADMIN_RESET		6
+#define PW_ADMIN_REBOOT		7
+#define PW_PORT_ERROR		8
+#define PW_NAS_ERROR		9
+#define PW_NAS_REQUEST		10
+#define PW_NAS_REBOOT		11
+#define PW_PORT_UNNEEDED	12
+#define PW_PORT_PREEMPTED	13
+#define PW_PORT_SUSPENDED	14
+#define PW_SERVICE_UNAVAILABLE	15
+#define PW_CALLBACK		    16
+#define PW_USER_ERROR		17
+#define PW_HOST_REQUEST		18
+
+/* NAS PORT TYPES */
+
+#define PW_ASYNC		    0
+#define PW_SYNC			    1
+#define PW_ISDN_SYNC		2
+#define PW_ISDN_SYNC_V120	3
+#define PW_ISDN_SYNC_V110	4
+#define PW_VIRTUAL		    5
+
+/* AUTHENTIC TYPES */
+
+#define PW_RADIUS	1
+#define PW_LOCAL	2
+#define PW_REMOTE	3
+
+/* Server data structures */
+
+typedef struct dict_attr
+{
+	char              name[NAME_LENGTH + 1];	//!< attribute name.
+	int               value;			//!< attribute index.
+	int               type;				//!< string, int, etc..
+	struct dict_attr *next;
+} DICT_ATTR;
+
+typedef struct dict_value
+{
+	char               attrname[NAME_LENGTH +1];
+	char               name[NAME_LENGTH + 1];
+	int                value;
+	struct dict_value *next;
+} DICT_VALUE;
+
+typedef struct dict_vendor
+{
+	char               vendorname[NAME_LENGTH +1];
+	int                vendorpec;
+	struct dict_vendor *next;
+} DICT_VENDOR;
+
+typedef struct value_pair
+{
+	char               name[NAME_LENGTH + 1];
+	int                attribute;
+	int                type;
+	uint32_t           lvalue;
+	char               strvalue[AUTH_STRING_LEN + 1];
+	struct value_pair *next;
+} VALUE_PAIR;
+
+/* Define return codes from "SendServer" utility */
+
+#define NET_ERR_RC  -3  // Ошибка создания сокета, соединения/отправки/приема
+#define BADRESP_RC	-2  // Неверный пароль
+#define ERROR_RC	-1
+#define OK_RC		0
+#define TIMEOUT_RC	1
+#define REJECT_RC	2  // Неверный логин
+#define USER_RC     3
+#define ADMIN_RC    4
+
+typedef struct send_data /* Used to pass information to sendserver() function */
+{
+	uint8_t        code;		//!< RADIUS packet code.
+	uint8_t        seq_nbr;		//!< Packet sequence number.
+	char           *server;		//!< Name/addrress of RADIUS server.
+	int            svc_port;	//!< RADIUS protocol destination port.
+	char           *secret;		//!< Shared secret of RADIUS server.
+	int            timeout;		//!< Session timeout in seconds.
+	int            retries;
+	VALUE_PAIR     *send_pairs;     //!< More a/v pairs to send.
+	VALUE_PAIR     *receive_pairs;  //!< Where to place received a/v pairs.
+} SEND_DATA;
+
+#ifndef MIN
+#define MIN(a, b)     ((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a, b)     ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX	1024
+#endif
+
+typedef struct env
+{
+	int maxsize, size;
+	char **env;
+} ENV;
+
+#define ENV_SIZE	128
+
+__BEGIN_DECLS
+
+/* Function prototypes */
+
+/* avpair.c */
+
+VALUE_PAIR *rc_avpair_add(rc_handle const *, VALUE_PAIR **, int, void const *, int, int);
+int rc_avpair_assign(VALUE_PAIR *, void const *, int);
+VALUE_PAIR *rc_avpair_new(rc_handle const *, int, void const *, int, int);
+VALUE_PAIR *rc_avpair_gen(rc_handle const *, VALUE_PAIR *, unsigned char const *, int, int);
+VALUE_PAIR *rc_avpair_get(VALUE_PAIR *, int, int);
+void rc_avpair_insert(VALUE_PAIR **, VALUE_PAIR *, VALUE_PAIR *);
+void rc_avpair_free(VALUE_PAIR *);
+int rc_avpair_parse(rc_handle const *, char const *, VALUE_PAIR **);
+int rc_avpair_tostr(rc_handle const *, VALUE_PAIR *, char *, int, char *, int);
+char *rc_avpair_log(rc_handle const *, VALUE_PAIR *, char *buf, size_t buf_len);
+//VALUE_PAIR *rc_avpair_readin(rc_handle const *, FILE *);
+
+/* buildreq.c */
+
+void rc_buildreq(rc_handle const *, SEND_DATA *, int, char *, unsigned short, char *, int, int);
+unsigned char rc_get_id();
+int rc_auth(rc_handle *, uint32_t, VALUE_PAIR *, VALUE_PAIR **, char *);
+int rc_auth_proxy(rc_handle *, VALUE_PAIR *, VALUE_PAIR **, char *);
+int rc_acct(rc_handle *, uint32_t, VALUE_PAIR *);
+int rc_acct_proxy(rc_handle *, VALUE_PAIR *);
+int rc_check(rc_handle *, char *, char *, unsigned short, char *);
+
+int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
+    char *msg, int add_nas_port, int request_type);
+
+/* clientid.c */
+
+int rc_read_mapfile(rc_handle *, char const *);
+uint32_t rc_map2id(rc_handle const *, char const *);
+void rc_map2id_free(rc_handle *);
+
+/* config.c */
+
+//rc_handle *rc_read_config(char const *);
+void rc_read_config(rc_handle* rh);
+char *rc_conf_str(rc_handle const *, char const *);
+int rc_conf_int(rc_handle const *, char const *);
+SERVER *rc_conf_srv(rc_handle const *, char const *);
+void rc_config_free(rc_handle *);
+int rc_add_config(rc_handle *, char const *, char const *, char const *, int);
+rc_handle *rc_config_init(rc_handle *);
+int test_config(rc_handle const *, char const *);
+
+/* dict.c */
+
+int rc_read_dictionary(rc_handle *, char const *);
+DICT_ATTR *rc_dict_getattr(rc_handle const *, int);
+DICT_ATTR *rc_dict_findattr(rc_handle const *, char const *);
+DICT_VALUE *rc_dict_findval(rc_handle const *, char const *);
+DICT_VENDOR *rc_dict_findvend(rc_handle const *, char const *);
+DICT_VENDOR *rc_dict_getvend(rc_handle const *, int);
+DICT_VALUE * rc_dict_getval(rc_handle const *, uint32_t, char const *);
+void rc_dict_free(rc_handle *);
+
+/* ip_util.c */
+
+
+int rc_good_ipaddr(char const *);
+unsigned short rc_getport(int);
+int rc_own_hostname(char *, int);
+struct sockaddr;
+int rc_get_srcaddr(struct sockaddr *, const struct sockaddr *);
+
+
+/* log.c */
+
+void rc_openlog(char const *);
+void rc_log(int, char const *, ...);
+
+/* sendserver.c */
+
+int rc_send_server(rc_handle *, SEND_DATA *, char *, unsigned flags);
+
+/* util.c */
+
+void rc_str2tm(char const *, struct tm *);
+char *rc_getifname(rc_handle *, char const *);
+char *rc_getstr(rc_handle *, char const *, int);
+void rc_mdelay(int);
+char *rc_mksid(rc_handle *);
+rc_handle *rc_new(void);
+void rc_destroy(rc_handle *);
+//char *rc_fgetln(FILE *, size_t *);
+double rc_getctime(void);
+
+/* env.c */
+
+struct env *rc_new_env(int);
+void rc_free_env(struct env *);
+int rc_add_env(struct env *, char const *, char const *);
+int rc_import_env(struct env *, char const **);
+
+/* md5.c */
+
+void rc_md5_calc(unsigned char *, unsigned char const *, unsigned int);
+
+__END_DECLS
+
+#endif /* FREERADIUS_CLIENT_H */

+ 189 - 0
thirdparty/FreeRadius/include/includes.h

@@ -0,0 +1,189 @@
+/*
+ * $Id: includes.h,v 1.6 2007/06/21 18:07:22 cparker Exp $
+ *
+ * Copyright (C) 1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#ifndef RC_INCLUDES_H
+# define RC_INCLUDES_H
+
+#include "radius_config.h"
+#include "rtc.h"
+#include "rng.h"
+
+/* AIX requires this to be the first thing in the file.  */
+#ifndef __GNUC__
+# if HAVE_ALLOCA_H
+#  include <alloca.h>
+# else
+#  ifdef _AIX
+#   pragma alloca
+#  else
+#   ifndef alloca /* predefined by HP cc +Olibcalls */
+     char *alloca ();
+#   endif
+#  endif
+# endif
+#endif
+
+//#include <sys/types.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+# include <stdarg.h>
+#else
+# include <stdarg.h>
+# ifndef HAVE_STRCHR
+#  define strchr index
+#  define strrchr rindex
+# endif
+#endif
+
+/* I realize that this is ugly and unsafe.. :( */
+#ifndef HAVE_SNPRINTF
+# define snprintf(buf, len, format, ...) sprintf(buf, format, __VA_ARGS__)
+#endif
+#ifndef HAVE_VSNPRINTF
+# define vsnprintf(buf, len, format, ap) vsprintf(buf, format, ap)
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_FCNTL_H
+# include <sys/fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_FILE_H
+# include <sys/file.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#ifdef HAVE_SYS_UTSNAME_H
+# include <sys/utsname.h>
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_CRYPT_H
+# include <crypt.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX        1024
+#endif
+
+#ifndef UCHAR_MAX
+# ifdef  __STDC__
+#  define UCHAR_MAX       255U
+# else
+#  define UCHAR_MAX       255
+# endif
+#endif
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#if defined(HAVE_SIGNAL_H)
+# include <signal.h>
+#endif
+#if defined(HAVE_SYS_SIGNAL_H)
+# include <sys/signal.h>
+#endif
+
+#ifdef NEED_SIG_PROTOTYPES
+int sigemptyset(sigset_t *);
+int sigaddset(sigset_t *, int);
+int sigprocmask (int, sigset_t *, sigset_t *);
+#endif
+
+#if HAVE_GETOPT_H
+# include <getopt.h>
+#endif
+
+#if defined(HAVE_SHADOW_H) && defined(HAVE_SHADOW_PASSWORDS)
+# include <shadow.h>
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+/*
+ * prefer srandom/random over srand/rand as there generator has a
+ * better distribution of the numbers on certain systems.
+ * on Linux both generators are identical.
+ */
+#ifndef HAVE_RANDOM
+# ifdef HAVE_RAND
+# define srandom        srand
+# define random         GetRandomNumber
+# endif
+#endif
+
+/* rlib/lock.c */
+int do_lock_exclusive(FILE *);
+int do_unlock(FILE *);
+
+#endif

+ 53 - 0
thirdparty/FreeRadius/include/messages.h

@@ -0,0 +1,53 @@
+/*
+ * $Id: messages.h,v 1.2 2004/02/23 20:10:39 sobomax Exp $
+ *
+ * Copyright (C) 1995,1996 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+/*
+ * Only messages that the user gets under normal use are in here.
+ * Error messages and such are still in the source code.
+ */
+
+#ifndef MESSAGES_H
+#define MESSAGES_H
+
+/* radlogin.c */
+
+#define SC_LOGIN	 "login: "
+#define SC_PASSWORD	 "Password: "
+
+#define SC_TIMEOUT	 "\r\nlogin timed out after %d seconds. Bye.\r\n"
+#define SC_EXCEEDED	 "Maximum login tries exceeded. Go away!\r\n"
+
+#define SC_RADIUS_OK	 "RADIUS: Authentication OK\r\n"
+#define SC_RADIUS_FAILED "RADIUS: Authentication failure\r\n"
+
+#define SC_LOCAL_OK	 "local: Authentication OK\r\n"
+#define SC_LOCAL_FAILED	 "local: Authentication failure\r\n"
+#define SC_NOLOGIN	 "\r\nSystem closed for maintenance. Try again later...\r\n"
+
+#define SC_SERVER_REPLY	 "RADIUS: %s"
+
+#define SC_DEFAULT_ISSUE "(\\I)\r\n\r\n\\S \\R (\\N) (port \\L)\r\n\r\n"
+
+/* radacct.c */
+
+#define SC_ACCT_OK	 "RADIUS accounting OK\r\n"
+#define SC_ACCT_FAILED	 "RADIUS accounting failed (RC=%i)\r\n"
+
+/* radstatus.c */
+
+#define SC_STATUS_FAILED	"RADIUS: Status failure\r\n"
+
+#endif /* MESSAGES_H */

+ 28 - 0
thirdparty/FreeRadius/include/pathnames.h

@@ -0,0 +1,28 @@
+/*
+ * $Id: pathnames.h,v 1.2 2004/02/23 20:10:39 sobomax Exp $
+ *
+ * Copyright (C) 1995,1996 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#ifndef PATHNAMES_H
+#define PATHNAMES_H
+
+#define _PATH_DEV_URANDOM		"/dev/urandom"		/* Linux only */
+#define _PATH_ETC_ISSUE			"/etc/issue"
+
+/* normally defined in the Makefile */
+#ifndef _PATH_ETC_RADIUSCLIENT_CONF
+#  define _PATH_ETC_RADIUSCLIENT_CONF	"/etc/radiusclient.conf"
+#endif
+
+#endif /* PATHNAMES_H */

+ 893 - 0
thirdparty/FreeRadius/lib/avpair.c

@@ -0,0 +1,893 @@
+/*
+ * $Id: avpair.c,v 1.26 2010/06/15 09:22:52 aland Exp $
+ *
+ * Copyright (C) 1995 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include "util.h"
+#include "def.h"
+
+/** Adds an attribute-value pair to the given list
+ *
+ * @note Always appends the new pair to the end of the list.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param list a #VALUE_PAIR array of values; initially must be %NULL.
+ * @param attrid The attribute of the pair to add (e.g., %PW_USER_NAME).
+ * @param pval the value (e.g., the actual username).
+ * @param len the length of @pval, or -1 if to calculate (in case of strings).
+ * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
+ * @return pointer to added a/v pair upon success, NULL pointer upon failure.
+ */
+VALUE_PAIR *rc_avpair_add (rc_handle const *rh, VALUE_PAIR **list, int attrid, void const *pval, int len, int vendorpec)
+{
+	VALUE_PAIR     *vp;
+
+	vp = rc_avpair_new (rh, attrid, pval, len, vendorpec);
+
+	if (vp != NULL)
+	{
+		rc_avpair_insert (list, NULL, vp);
+	}
+
+	return vp;
+}
+
+/** Assigns the given value to an attribute-value pair
+ *
+ * @param vp a pointer to a #VALUE_PAIR structure.
+ * @param pval the value (e.g., the actual username).
+ * @param len the length of @pval, or -1 if to calculate (in case of strings).
+ * @return 0 on success or -1 on failure.
+ */
+int rc_avpair_assign (VALUE_PAIR *vp, void const *pval, int len)
+{
+#if 1
+	switch (vp->type)
+	{
+		case PW_TYPE_STRING:
+			if (len == -1)
+				len = (uint32_t)strlen((char const *)pval);
+			if (len > AUTH_STRING_LEN) {
+		        	rc_log(LOG_ERR, "rc_avpair_assign: bad attribute length");
+		        	return -1;
+			}
+			memcpy(vp->strvalue, (char const *)pval, len);
+			vp->strvalue[len] = '\0';
+			vp->lvalue = len;
+			break;
+
+		case PW_TYPE_DATE:
+		case PW_TYPE_INTEGER:
+	        case PW_TYPE_IPADDR:
+			vp->lvalue = * (uint32_t *) pval;
+			break;
+	        case PW_TYPE_IPV6ADDR:
+			if (len != 16) {
+		        	rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 length");
+		        	return -1;
+			}
+			memcpy(vp->strvalue, (char const *)pval, len);
+			vp->lvalue = len;
+			break;
+
+	        case PW_TYPE_IPV6PREFIX:
+			if (len < 2 || len > 18) {
+		        	rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 prefix length");
+		        	return -1;
+			}
+			memcpy(vp->strvalue, (char const *)pval, len);
+			vp->lvalue = len;
+			break;
+
+		default:
+			rc_log(LOG_ERR, "rc_avpair_assign: unknown attribute %d", vp->type);
+			return -1;
+	}
+#endif    
+	return 0;
+}
+
+/** Make a new attribute-value pair with given parameters
+ *
+ * @param rh a handle to parsed configuration.
+ * @param attrid The attribute of the pair to add (e.g., %PW_USER_NAME).
+ * @param pval the value (e.g., the actual username).
+ * @param len the length of pval, or -1 if to calculate (in case of strings).
+ * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
+ * @return pointer to generated a/v pair when successful, NULL when failure.
+ */
+VALUE_PAIR *rc_avpair_new (rc_handle const *rh, int attrid, void const *pval, int len, int vendorpec)
+{
+ 
+	VALUE_PAIR     *vp = NULL;
+	DICT_ATTR      *pda;
+
+	attrid = attrid | (vendorpec << 16);
+	if ((pda = rc_dict_getattr (rh, attrid)) == NULL)
+	{
+		rc_log(LOG_ERR,"rc_avpair_new: unknown attribute %d", attrid);
+		return NULL;
+	}
+	if (vendorpec != 0 && rc_dict_getvend(rh, vendorpec) == NULL)
+	{
+		rc_log(LOG_ERR,"rc_avpair_new: unknown Vendor-Id %d", vendorpec);
+		return NULL;
+	}
+	if ((vp = malloc (sizeof (VALUE_PAIR))) != NULL)
+	{
+		strlcpy (vp->name, pda->name, sizeof (vp->name));
+		vp->attribute = attrid;
+		vp->next = NULL;
+		vp->type = pda->type;
+		if (rc_avpair_assign (vp, pval, len) == 0)
+		{
+			/* XXX: Fix up Digest-Attributes */
+			switch (vp->attribute) {
+			case PW_DIGEST_REALM:
+			case PW_DIGEST_NONCE:
+			case PW_DIGEST_METHOD:
+			case PW_DIGEST_URI:
+			case PW_DIGEST_QOP:
+			case PW_DIGEST_ALGORITHM:
+			case PW_DIGEST_BODY_DIGEST:
+			case PW_DIGEST_CNONCE:
+			case PW_DIGEST_NONCE_COUNT:
+			case PW_DIGEST_USER_NAME:
+				/* overlapping! */
+				if (vp->lvalue > AUTH_STRING_LEN - 2)
+					vp->lvalue = AUTH_STRING_LEN - 2;
+				memmove(&vp->strvalue[2], &vp->strvalue[0], vp->lvalue);
+				vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;
+				vp->lvalue += 2;
+				vp->strvalue[1] = vp->lvalue;
+				vp->strvalue[vp->lvalue] = '\0';
+				vp->attribute = PW_DIGEST_ATTRIBUTES;
+			default:
+				break;
+			}
+			return vp;
+		}
+		free (vp);
+		vp = NULL;
+	}
+	else
+	{
+		rc_log(LOG_CRIT,"rc_avpair_new: out of memory");
+	}
+
+	return vp;
+}
+
+/** Takes attribute/value pairs from buffer and builds a value_pair list using allocated memory
+ *
+ * @note Uses recursion.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param pair a pointer to a #VALUE_PAIR structure.
+ * @param ptr the value (e.g., the actual username).
+ * @param length the length of ptr, or -1 if to calculate (in case of strings).
+ * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
+ * @return value_pair list or %NULL on failure.
+ */
+VALUE_PAIR *rc_avpair_gen(rc_handle const *rh, VALUE_PAIR *pair, unsigned char const *ptr,
+			  int length, int vendorpec)
+{
+#if 1
+	int attribute, attrlen, x_len;
+	unsigned char const *x_ptr;
+	uint32_t lvalue;
+	DICT_ATTR *attr;
+	VALUE_PAIR *rpair;
+	char buffer[(AUTH_STRING_LEN * 2) + 1];
+	/* For hex string conversion. */
+	char hex[3];
+
+	if (length < 2) {
+		rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
+		    "invalid length");
+		goto shithappens;
+	}
+	attrlen = ptr[1];
+	if (length < attrlen || attrlen < 2) {
+		rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
+		    "invalid length");
+		goto shithappens;
+	}
+
+	/* Advance to the next attribute and process recursively */
+	if (length != attrlen) {
+		pair = rc_avpair_gen(rh, pair, ptr + attrlen, length - attrlen,
+		    vendorpec);
+		if (pair == NULL)
+			return NULL;
+	}
+
+	/* Actual processing */
+	attribute = ptr[0] | (vendorpec << 16);
+	ptr += 2;
+	attrlen -= 2;
+
+	/* VSA */
+	if (attribute == PW_VENDOR_SPECIFIC) {
+		if (attrlen < 4) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received VSA "
+			    "attribute with invalid length");
+			goto skipit;
+		}
+		memcpy(&lvalue, ptr, 4);
+		vendorpec = ntohl(lvalue);
+		if (rc_dict_getvend(rh, vendorpec) == NULL) {
+			/* Warn and skip over the unknown VSA */
+			rc_log(LOG_WARNING, "rc_avpair_gen: received VSA "
+			    "attribute with unknown Vendor-Id %d", vendorpec);
+			goto skipit;
+		}
+		/* Process recursively */
+		return rc_avpair_gen(rh, pair, ptr + 4, attrlen - 4,
+		    vendorpec);
+	}
+
+	/* Normal */
+	attr = rc_dict_getattr(rh, attribute);
+	if (attr == NULL) {
+		buffer[0] = '\0';	/* Initial length. */
+		x_ptr = ptr;
+		for (x_len = attrlen; x_len > 0; x_len--, x_ptr++) {
+			snprintf(hex, sizeof(hex), "%2.2X", x_ptr[0]);
+			strcat(buffer, hex);
+		}
+		if (vendorpec == 0) {
+			rc_log(LOG_WARNING, "rc_avpair_gen: received "
+			    "unknown attribute %d of length %d: 0x%s",
+			    attribute, attrlen + 2, buffer);
+		} else {
+			rc_log(LOG_WARNING, "rc_avpair_gen: received "
+			    "unknown VSA attribute %d, vendor %d of "
+			    "length %d: 0x%s", attribute & 0xffff,
+			    VENDOR(attribute), attrlen + 2, buffer);
+		}
+		goto skipit;
+	}
+
+	rpair = malloc(sizeof(*rpair));
+	if (rpair == NULL) {
+		rc_log(LOG_CRIT, "rc_avpair_gen: out of memory");
+		goto shithappens;
+	}
+	memset(rpair, '\0', sizeof(*rpair));
+
+	/* Insert this new pair at the beginning of the list */
+	rpair->next = pair;
+	pair = rpair;
+	strcpy(pair->name, attr->name);
+	pair->attribute = attr->value;
+	pair->type = attr->type;
+
+	switch (attr->type) {
+	case PW_TYPE_STRING:
+		memcpy(pair->strvalue, (char *)ptr, (size_t)attrlen);
+		pair->strvalue[attrlen] = '\0';
+		pair->lvalue = attrlen;
+		break;
+
+	case PW_TYPE_INTEGER:
+		if (attrlen != 4) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received INT "
+			    "attribute with invalid length");
+			goto skipit;
+		}
+	case PW_TYPE_IPADDR:
+		if (attrlen != 4) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received IPADDR"
+			    " attribute with invalid length");
+			goto skipit;
+		}
+		memcpy((char *)&lvalue, (char *)ptr, 4);
+		pair->lvalue = ntohl(lvalue);
+		break;
+	case PW_TYPE_IPV6ADDR:
+		if (attrlen != 16) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received IPV6ADDR"
+			    " attribute with invalid length");
+			goto skipit;
+		}
+		memcpy(pair->strvalue, (char *)ptr, 16);
+		pair->lvalue = attrlen;
+		break;
+	case PW_TYPE_IPV6PREFIX:
+		if (attrlen > 18 || attrlen < 2) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received IPV6PREFIX"
+			    " attribute with invalid length: %d", attrlen);
+			goto skipit;
+		}
+		memcpy(pair->strvalue, (char *)ptr, attrlen);
+		pair->lvalue = attrlen;
+		break;
+	case PW_TYPE_DATE:
+		if (attrlen != 4) {
+			rc_log(LOG_ERR, "rc_avpair_gen: received DATE "
+			    "attribute with invalid length");
+			goto skipit;
+		}
+
+	default:
+		rc_log(LOG_WARNING, "rc_avpair_gen: %s has unknown type",
+		    attr->name);
+		goto skipit;
+	}
+
+skipit:
+	return pair;
+
+shithappens:
+	while (pair != NULL) {
+		rpair = pair->next;
+		free(pair);
+		pair = rpair;
+	}
+#endif    
+	return NULL;
+}
+
+/** Find the first attribute value-pair (which matches the given attribute) from the specified value-pair list
+ *
+ * @param vp a pointer to a #VALUE_PAIR structure.
+ * @param attrid The attribute of the pair to find (e.g., %PW_USER_NAME).
+ * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
+ * @return the value pair found.
+ */
+VALUE_PAIR *rc_avpair_get (VALUE_PAIR *vp, int attrid, int vendorpec)
+{
+	for (; vp != NULL && !(ATTRID(vp->attribute) == ATTRID(attrid) &&
+	    VENDOR(vp->attribute) == vendorpec); vp = vp->next)
+	{
+		continue;
+	}
+  
+	return vp;
+}
+
+/** Insert a VALUE_PAIR into a list
+ *
+ * Given the address of an existing list "a" and a pointer to an entry "p" in that list, add the value pair "b" to
+ * the "a" list after the "p" entry.  If "p" is NULL, add the value pair "b" to the end of "a".
+ *
+ * @param a a #VALUE_PAIR array of values.
+ * @param p a pointer to a #VALUE_PAIR in a.
+ * @param b The #VALUE_PAIR pointer to add in a.
+ */
+void rc_avpair_insert(VALUE_PAIR **a, VALUE_PAIR *p, VALUE_PAIR *b)
+{
+	VALUE_PAIR     *this_node = NULL;
+	VALUE_PAIR     *vp;
+
+	if (b->next != NULL)
+	{
+		rc_log(LOG_CRIT, "rc_avpair_insert: value pair (0x%p) next ptr. (0x%p) not NULL", b, b->next);
+		abort ();
+	}
+
+	if (*a == NULL)
+	{
+		*a = b;
+		return;
+	}
+
+	vp = *a;
+
+	if ( p == NULL) /* run to end of "a" list */
+	{
+		while (vp != NULL)
+		{
+			this_node = vp;
+			vp = vp->next;
+		}
+	}
+	else /* look for the "p" entry in the "a" list */
+	{
+		this_node = *a;
+		while (this_node != NULL)
+		{
+			if (this_node == p)
+			{
+				break;
+			}
+			this_node = this_node->next;
+		}
+	}
+
+	b->next = this_node->next;
+	this_node->next = b;
+
+	return;
+}
+
+/** Frees all value_pairs in the list
+ *
+ * @param pair a pointer to a VALUE_PAIR structure.
+ */
+void rc_avpair_free (VALUE_PAIR *pair)
+{
+#if 0  
+	VALUE_PAIR     *next;
+
+	while (pair != NULL)
+	{
+		next = pair->next;
+		free (pair);
+		pair = next;
+	}
+#endif    
+}
+
+/** Copy a data field from the buffer
+ *
+ * Advance the buffer past the data field. Ensure that no more than len - 1 bytes are copied and that resulting
+ * string is terminated with '\0'.
+ *
+ * @param string the provided string to copy.
+ * @param uptr the current position of the buffer.
+ * @param stopat characters to which parsing should stop.
+ * @param len the maximum length of string.
+ */
+static void rc_fieldcpy(char *string, char const **uptr, char const *stopat, size_t len)
+{
+#if 0  
+	char const *ptr, *estring;
+
+	ptr = *uptr;
+	estring = string + len - 1;
+	if (*ptr == '"')
+	{
+		ptr++;
+		while (*ptr != '"' && *ptr != '\0' && *ptr != '\n')
+		{
+			if (string < estring)
+				*string++ = *ptr;
+			ptr++;
+		}
+		if (*ptr == '"')
+		{
+			ptr++;
+		}
+		*string = '\0';
+		*uptr = ptr;
+		return;
+	}
+
+	while (*ptr != '\0' && strchr(stopat, *ptr) == NULL)
+	{
+		if (string < estring)
+			*string++ = *ptr;
+		ptr++;
+	}
+	*string = '\0';
+	*uptr = ptr;
+#endif
+	return;
+}
+
+#define PARSE_MODE_NAME		0
+#define PARSE_MODE_EQUAL	1
+#define PARSE_MODE_VALUE	2
+#define PARSE_MODE_INVALID	3
+
+/** Parses the buffer to extract the attribute-value pairs
+ *
+ * @param rh a handle to parsed configuration.
+ * @param buffer the buffer to be parsed.
+ * @param first_pair an allocated array of values.
+ * @return 0 on successful parse of attribute-value pair, or -1 on syntax (or other) error detected.
+ */
+int rc_avpair_parse (rc_handle const *rh, char const *buffer, VALUE_PAIR **first_pair)
+{
+#if 0  
+	int             mode;
+	char            attrstr[AUTH_ID_LEN];
+	char            valstr[AUTH_STRING_LEN + 1], *p;
+	DICT_ATTR      *attr = NULL;
+	DICT_VALUE     *dval;
+	VALUE_PAIR     *pair;
+	VALUE_PAIR     *link;
+	struct tm      *tm;
+	time_t          timeval;
+
+	mode = PARSE_MODE_NAME;
+	while (*buffer != '\n' && *buffer != '\0')
+	{
+		if (*buffer == ' ' || *buffer == '\t')
+		{
+			buffer++;
+			continue;
+		}
+
+		switch (mode)
+		{
+		    case PARSE_MODE_NAME:		/* Attribute Name */
+			rc_fieldcpy (attrstr, &buffer, " \t\n=,", sizeof(attrstr));
+			if ((attr =
+				rc_dict_findattr (rh, attrstr)) == NULL)
+			{
+				rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute");
+				if (*first_pair) {
+					rc_avpair_free(*first_pair);
+					*first_pair = NULL;
+				}
+				return -1;
+			}
+			mode = PARSE_MODE_EQUAL;
+			break;
+
+		    case PARSE_MODE_EQUAL:		/* Equal sign */
+			if (*buffer == '=')
+			{
+				mode = PARSE_MODE_VALUE;
+				buffer++;
+			}
+			else
+			{
+				rc_log(LOG_ERR, "rc_avpair_parse: missing or misplaced equal sign");
+				if (*first_pair) {
+					rc_avpair_free(*first_pair);
+					*first_pair = NULL;
+				}
+				return -1;
+			}
+			break;
+
+		    case PARSE_MODE_VALUE:		/* Value */
+			rc_fieldcpy (valstr, &buffer, " \t\n,", sizeof(valstr));
+
+			if ((pair = malloc (sizeof (VALUE_PAIR))) == NULL)
+			{
+				rc_log(LOG_CRIT, "rc_avpair_parse: out of memory");
+				if (*first_pair) {
+					rc_avpair_free(*first_pair);
+					*first_pair = NULL;
+				}
+				return -1;
+			}
+			strcpy (pair->name, attr->name);
+			pair->attribute = attr->value;
+			pair->type = attr->type;
+
+			switch (pair->type)
+			{
+
+			    case PW_TYPE_STRING:
+				strcpy (pair->strvalue, valstr);
+				pair->lvalue = (uint32_t)strlen(valstr);
+				break;
+
+			    case PW_TYPE_INTEGER:
+				if (isdigit (*valstr))
+				{
+					pair->lvalue = atoi (valstr);
+				}
+				else
+				{
+					if ((dval = rc_dict_findval (rh, valstr))
+							== NULL)
+					{
+						rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute value: %s", valstr);
+						if (*first_pair) {
+							rc_avpair_free(*first_pair);
+							*first_pair = NULL;
+						}
+						free (pair);
+						return -1;
+					}
+					else
+					{
+						pair->lvalue = dval->value;
+					}
+				}
+				break;
+
+			    case PW_TYPE_IPADDR:
+			    	if (inet_pton(AF_INET, valstr, &pair->lvalue) == 0) {
+			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv4 address %s", valstr);
+			    		free(pair);
+			    		return -1;
+			    	}
+
+                                pair->lvalue = ntohl(pair->lvalue);
+				break;
+
+			    case PW_TYPE_IPV6ADDR:
+			    	if (inet_pton(AF_INET6, valstr, pair->strvalue) == 0) {
+			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 address %s", valstr);
+			    		free(pair);
+			    		return -1;
+			    	}
+				pair->lvalue = 16;
+				break;
+
+			    case PW_TYPE_IPV6PREFIX:
+			    	p = strchr(valstr, '/');
+			    	if (p == NULL) {
+			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
+			    		free(pair);
+			    		return -1;
+			    	}
+			    	*p = 0;
+			    	p++;
+			    	pair->strvalue[0] = 0;
+			    	pair->strvalue[1] = atoi(p);
+
+			    	if (inet_pton(AF_INET6, valstr, pair->strvalue+2) == 0) {
+			    		rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
+			    		free(pair);
+			    		return -1;
+			    	}
+				pair->lvalue = 2+16;
+				break;
+
+			    case PW_TYPE_DATE:
+				timeval = time (0);
+				tm = localtime (&timeval);
+				tm->tm_hour = 0;
+				tm->tm_min = 0;
+				tm->tm_sec = 0;
+				rc_str2tm (valstr, tm);
+#ifdef TIMELOCAL
+				pair->lvalue = (uint32_t) timelocal (tm);
+#else	/* TIMELOCAL */
+				pair->lvalue = (uint32_t) mktime (tm);
+#endif	/* TIMELOCAL */
+				break;
+
+			    default:
+				rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute type %d", pair->type);
+				if (*first_pair) {
+					rc_avpair_free(*first_pair);
+					*first_pair = NULL;
+				}
+				free (pair);
+				return -1;
+			}
+
+			/* XXX: Fix up Digest-Attributes */
+			switch (pair->attribute) {
+			case PW_DIGEST_REALM:
+			case PW_DIGEST_NONCE:
+			case PW_DIGEST_METHOD:
+			case PW_DIGEST_URI:
+			case PW_DIGEST_QOP:
+			case PW_DIGEST_ALGORITHM:
+			case PW_DIGEST_BODY_DIGEST:
+			case PW_DIGEST_CNONCE:
+			case PW_DIGEST_NONCE_COUNT:
+			case PW_DIGEST_USER_NAME:
+				/* overlapping! */
+				if (pair->lvalue > AUTH_STRING_LEN - 2)
+					pair->lvalue = AUTH_STRING_LEN - 2;
+				memmove(&pair->strvalue[2], &pair->strvalue[0], pair->lvalue);
+				pair->strvalue[0] = pair->attribute - PW_DIGEST_REALM + 1;
+				pair->lvalue += 2;
+				pair->strvalue[1] = pair->lvalue;
+				pair->strvalue[pair->lvalue] = '\0';
+				pair->attribute = PW_DIGEST_ATTRIBUTES;
+			}
+
+			pair->next = NULL;
+
+			if (*first_pair == NULL)
+			{
+				*first_pair = pair;
+			}
+			else
+			{
+				link = *first_pair;
+				while (link->next != NULL)
+				{
+					link = link->next;
+				}
+				link->next = pair;
+			}
+
+			mode = PARSE_MODE_NAME;
+			break;
+
+		    default:
+			mode = PARSE_MODE_NAME;
+			break;
+		}
+	}
+#endif
+	return 0;
+}
+
+/** Translate an av_pair into two strings
+ *
+ * @param rh a handle to parsed configuration.
+ * @param pair a pointer to a VALUE_PAIR structure.
+ * @param name the name of the pair.
+ * @param ln the size of name.
+ * @param value the value of the pair.
+ * @param lv the size of value.
+ * @return 0 on success, -1 on failure.
+ */
+int rc_avpair_tostr (rc_handle const *rh, VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
+{
+#if 0  
+	DICT_VALUE     *dval;
+	char            buffer[32];
+	struct in_addr  inad;
+	unsigned char  *ptr;
+	unsigned int    pos;
+
+	*name = *value = '\0';
+
+	if (!pair || pair->name[0] == '\0') {
+		rc_log(LOG_ERR, "rc_avpair_tostr: pair is NULL or empty");
+		return -1;
+	}
+
+	strlcpy(name, pair->name, (size_t) ln);
+
+	switch (pair->type)
+	{
+	    case PW_TYPE_STRING:
+	    	lv--;
+	    	pos = 0;
+		ptr = (unsigned char *) pair->strvalue;
+		if (pair->attribute == PW_DIGEST_ATTRIBUTES) {
+			pair->strvalue[*(ptr + 1)] = '\0';
+			ptr += 2;
+		}
+		while (*ptr != '\0')
+		{
+			if (!(isprint (*ptr)))
+			{
+				if (lv >= 4) {
+					snprintf (&value[pos], lv, "\\%03o", *ptr);
+					pos += 4;
+					lv -= 4;
+				} else {
+					break;
+				}
+			}
+			else
+			{
+				if (lv > 0) {
+					value[pos++] = *ptr;
+					lv--;
+				} else {
+					break;
+				}
+			}
+			ptr++;
+		}
+		if (lv > 0)
+			value[pos++] = 0;
+		else
+			value[pos-1] = 0;
+		break;
+
+	    case PW_TYPE_INTEGER:
+		dval = rc_dict_getval (rh, pair->lvalue, pair->name);
+		if (dval != NULL)
+		{
+			strlcpy(value, dval->name, (size_t) lv);
+		}
+		else
+		{
+			snprintf(value, lv, "%ld", (long int)pair->lvalue);
+		}
+		break;
+
+	    case PW_TYPE_IPADDR:
+		inad.s_addr = htonl(pair->lvalue);
+		strlcpy (value, inet_ntoa (inad), (size_t) lv);
+		break;
+
+	    case PW_TYPE_IPV6ADDR:
+	    	if (inet_ntop(AF_INET6, pair->strvalue, value, lv) == NULL)
+	    		return -1;
+		break;
+
+	    case PW_TYPE_IPV6PREFIX: {
+	    	uint8_t ip[16];
+	    	char txt[48];
+	    	if (pair->lvalue < 2)
+	    		return -1;
+
+	    	memset(ip, 0, sizeof(ip));
+	    	memcpy(ip, pair->strvalue+2, pair->lvalue-2);
+
+	    	if (inet_ntop(AF_INET6, ip, txt, sizeof(txt)) == NULL)
+	    		return -1;
+		snprintf(value, lv, "%s/%u", txt, (unsigned)pair->strvalue[1]);
+
+		break;
+	    }
+	    case PW_TYPE_DATE:
+		strftime (value, lv, "%m/%d/%y %H:%M:%S",
+			  gmtime ((time_t *) & pair->lvalue));
+		break;
+
+	    default:
+		rc_log(LOG_ERR, "rc_avpair_tostr: unknown attribute type %d", pair->type);
+		return -1;
+		break;
+	}
+#endif
+	return 0;
+}
+
+/** Format a sequence of attribute value pairs into a printable string
+ *
+ * The caller should provide a storage buffer and the buffer length.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param pair a pointer to a #VALUE_PAIR structure.
+ * @param buf will hold the string output of the pair.
+ * @param len the size of buf.
+ * @return a pointer to provided storage buffer.
+ */
+char *rc_avpair_log(rc_handle const *rh, VALUE_PAIR *pair, char *buf, size_t buf_len)
+{
+#if 0  
+	size_t len, nlen;
+	VALUE_PAIR *vp;
+	char name[33], value[256];
+
+	len = 0;
+	for (vp = pair; vp != NULL; vp = vp->next) {
+		if (rc_avpair_tostr(rh, vp, name, sizeof(name), value,
+		    sizeof(value)) == -1)
+		        return NULL;
+		nlen = len + 32 + 3 + strlen(value) + 2 + 2;
+		if(nlen<buf_len-1) {
+			sprintf(buf + len, "%-32s = '%s'\n", name, value);
+		} else return buf;
+		len = nlen - 1;
+	}
+#endif    
+	return buf;
+}
+
+/** Get a sequence of attribute value pairs from the file input and make them into a list of value_pairs
+ *
+ * @param rh a handle to parsed configuration.
+ * @param input a %FILE handle.
+ * @return the array of value pairs.
+ */
+VALUE_PAIR *rc_avpair_readin(rc_handle const *rh, FILE *input)
+{
+	VALUE_PAIR *vp = NULL;
+#if 0  
+	char buffer[1024], *q;
+
+	while (fgets(buffer, sizeof(buffer), input) != NULL)
+	{
+		q = buffer;
+
+		while(*q && isspace(*q)) q++;
+
+		if ((*q == '\n') || (*q == '#') || (*q == '\0'))
+			continue;
+
+		if (rc_avpair_parse(rh, q, &vp) < 0) {
+			rc_log(LOG_ERR, "rc_avpair_readin: malformed attribute: %s", buffer);
+			rc_avpair_free(vp);
+			return NULL;
+		}
+	}
+#endif
+	return vp;
+}

+ 178 - 0
thirdparty/FreeRadius/lib/buildreq.c

@@ -0,0 +1,178 @@
+/*
+ * $Id: buildreq.c,v 1.17 2010/02/04 10:27:09 aland Exp $
+ *
+ * Copyright (C) 1995,1997 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include "util.h"
+
+/** Build a skeleton RADIUS request using information from the config file
+ *
+ * @param rh a handle to parsed configuration.
+ * @param data a pointer to a #SEND_DATA structure.
+ * @param code one of standard RADIUS codes (e.g., %PW_ACCESS_REQUEST).
+ * @param server the name of the server.
+ * @param port the server's port number.
+ * @param secret the secret used by the server.
+ * @param timeout the timeout in seconds of a message.
+ * @param retries the number of retries.
+ */
+void rc_buildreq(rc_handle const *rh, SEND_DATA *data, int code, char *server, unsigned short port,
+		 char *secret, int timeout, int retries)
+{
+	data->server = server;
+	data->secret = secret;
+	data->svc_port = port;
+	data->seq_nbr = rc_get_id();
+	data->timeout = timeout;
+	data->retries = retries;
+	data->code = code;
+}
+
+/** Generates a random ID
+ *
+ * @return the random ID.
+ */
+unsigned char rc_get_id()
+{
+	return (unsigned char)(random() & UCHAR_MAX);
+}
+
+/** Builds an authentication/accounting request for port id client_port with the value_pairs send and submits it to a server
+ *
+ * @param rh a handle to parsed configuration.
+ * @param client_port the client port number to use (may be zero to use any available).
+ * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
+ * @param received an allocated array of received values.
+ * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
+ *	%PW_REPLY_MESSAGE received.
+ * @param add_nas_port if non-zero it will include %PW_NAS_PORT in sent pairs.
+ * @param request_type one of standard RADIUS codes (e.g., %PW_ACCESS_REQUEST).
+ * @return received value_pairs in received, messages from the server in msg and %OK_RC (0) on success, negative
+ *	on failure as return value.
+ */
+int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
+	   char *msg, int add_nas_port, int request_type)
+{
+	SEND_DATA   data;
+    VALUE_PAIR* myVp;
+	SERVER		*aaaserver;
+	int		    timeout = rc_conf_int(rh, "radius_timeout");
+	int		    retries = rc_conf_int(rh, "radius_retries");
+	int		    radius_deadtime = rc_conf_int(rh, "radius_deadtime");
+	unsigned	type;
+    int         result;
+
+    SERVER myServer;
+   
+    myVp = rc_avpair_get(send, PW_USER_PASSWORD, 0);
+    myServer.secret[0] = myVp->name;
+       
+    aaaserver = &myServer;
+    type = AUTH;
+    
+    if (aaaserver == NULL)
+		return ERROR_RC;
+
+	data.send_pairs = send;
+	data.receive_pairs = NULL;
+    
+    if (add_nas_port != 0) {
+		// Fill in NAS-Port
+		if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT,
+		    &client_port, 0, 0) == NULL)
+			return ERROR_RC;
+	}
+    
+	if (data.receive_pairs != NULL) {
+		rc_avpair_free(data.receive_pairs);
+		data.receive_pairs = NULL;
+	}
+	rc_buildreq(rh, &data, request_type, aaaserver->name[0],
+		    aaaserver->port[0], aaaserver->secret[0], timeout, retries);
+
+    // Делаем 3 попытки если есть какие-либо проблемы с обменом
+    for (uint8_t i = 0; i < 3; i++)
+    {
+        //printf ("Radius trying\r\n");
+        result = rc_send_server(rh, &data, msg, type);     
+                
+        if (result != NET_ERR_RC)
+            break;
+    }
+    
+    return result;
+    
+}
+
+/** Builds an authentication request for port id client_port with the value_pairs send and submits it to a server
+ *
+ * @param rh a handle to parsed configuration.
+ * @param client_port the client port number to use (may be zero to use any available).
+ * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
+ * @param received an allocated array of received values.
+ * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
+ *	%PW_REPLY_MESSAGE received.
+ * @return received value_pairs in @received, messages from the server in msg (if non-NULL),
+ *	and %OK_RC (0) on success, negative on failure as return value.
+ */
+int rc_auth(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
+    char *msg)
+{
+
+	//return rc_aaa(rh, client_port, send, received, msg, 1, PW_ACCESS_REQUEST);
+    return rc_aaa(rh, client_port, send, received, msg, 0, PW_ACCESS_REQUEST);
+}
+
+/** Builds an authentication request for proxying
+ *
+ * Builds an authentication request with the value_pairs send and submits it to a server.
+ * Works for a proxy; does not add IP address, and does does not rely on config file.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param client_port the client port number to use (may be zero to use any available).
+ * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
+ * @param received an allocated array of received values.
+ * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of
+ *	any %PW_REPLY_MESSAGE received.
+ * @return received value_pairs in @received, messages from the server in msg (if non-NULL)
+ *	and %OK_RC (0) on success, negative on failure as return value.
+ */
+int rc_auth_proxy(rc_handle *rh, VALUE_PAIR *send, VALUE_PAIR **received, char *msg)
+{
+	return rc_aaa(rh, 0, send, received, msg, 0, PW_ACCESS_REQUEST);
+}
+
+/** Builds an accounting request for port id client_port with the value_pairs at send
+ *
+ * @note NAS-IP-Address, NAS-Port and Acct-Delay-Time get filled in by this function, the rest has to be supplied.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param client_port the client port number to use (may be zero to use any available).
+ * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
+ * @return received value_pairs in @received, and %OK_RC (0) on success, negative on failure as return value.
+ */
+int rc_acct(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send)
+{
+	return rc_aaa(rh, client_port, send, NULL, NULL, 1, PW_ACCOUNTING_REQUEST);
+}
+
+/** Builds an accounting request with the value_pairs at send
+ *
+ * @param rh a handle to parsed configuration.
+ * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
+ * @return %OK_RC (0) on success, negative on failure as return value.
+ */
+int rc_acct_proxy(rc_handle *rh, VALUE_PAIR *send)
+{
+
+	return rc_aaa(rh, 0, send, NULL, NULL, 0, PW_ACCOUNTING_REQUEST);
+}
+

+ 943 - 0
thirdparty/FreeRadius/lib/config.c

@@ -0,0 +1,943 @@
+/*
+ * $Id: config.c,v 1.23 2010/04/28 14:26:15 aland Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include <fr_options.h>
+#include "util.h"
+
+extern OPTION      rcOptions;
+
+/** Find an option in the option list
+ *
+ * @param rh a handle to parsed configuration.
+ * @param optname the name of the option.
+ * @param type the option type.
+ * @return pointer to option on success, NULL otherwise.
+ */
+static OPTION *find_option(rc_handle const *rh, char const *optname, unsigned int type)
+{
+	int 	i;
+
+	/* there're so few options that a binary search seems not necessary */
+	for (i = 0; i < NUM_OPTIONS; i++) {
+		if (!strcmp(rh->config_options[i].name, optname) &&
+		    (rh->config_options[i].type & type))
+		{
+		    	return &rh->config_options[i];
+		}
+	}
+
+	return NULL;
+}
+
+/** Set a specific option doing type conversions
+ *
+ * @param filename the name of the config file (for logging purposes).
+ * @param line the line number in the file.
+ * @param p Value.
+ * @return 0 on success, -1 on failure.
+ */
+static int set_option_str(char const *filename, int line, OPTION *option, char const *p)
+{
+#if 0
+	if (p) {
+		option->val = (void *) strdup(p);
+		if (option->val == NULL) {
+			rc_log(LOG_CRIT, "read_config: out of memory");
+			return -1;
+		}
+	} else {
+		option->val = NULL;
+	}
+
+	return 0;
+#endif
+}
+
+static int set_option_int(char const *filename, int line, OPTION *option, char const *p)
+{
+	int *iptr;
+
+	if (p == NULL) {
+		rc_log(LOG_ERR, "%s: line %d: bogus option value", filename, line);
+		return -1;
+	}
+
+	if ((iptr = malloc(sizeof(*iptr))) == NULL) {
+		rc_log(LOG_CRIT, "read_config: out of memory");
+		return -1;
+	}
+
+	*iptr = atoi(p);
+	option->val = (void *) iptr;
+
+	return 0;
+}
+
+static int set_option_srv(char const *filename, int line, OPTION *option, char const *p)
+{
+#if 0  
+	SERVER *serv;
+	char *p_pointer;
+	char *p_dupe;
+	char *p_save;
+	char *q;
+	char *s;
+	struct servent *svp;
+
+	p_dupe = strdup(p);
+
+	if (p_dupe == NULL) {
+		rc_log(LOG_ERR, "%s: line %d: Invalid option or memory failure", filename, line);
+		return -1;
+	}
+
+	serv = (SERVER *) option->val;
+	if (serv == NULL) {
+		DEBUG(LOG_ERR, "option->val / server is NULL, allocating memory");
+		serv = malloc(sizeof(*serv));
+		if (serv == NULL) {
+			rc_log(LOG_CRIT, "read_config: out of memory");
+			free(p_dupe);
+			return -1;
+		}
+		memset(serv, 0, sizeof(*serv));
+		serv->max = 0;
+	}
+
+	p_pointer = strtok_r(p_dupe, ", \t", &p_save);
+
+	/* check to see for '[IPv6]:port' syntax */
+	if ((q = strchr(p_pointer,'[')) != NULL) {
+		*q = '\0';
+		q++;
+		p_pointer = q;
+
+		q = strchr(p_pointer, ']');
+		if (q == NULL) {
+			free(p_dupe);
+			rc_log(LOG_CRIT, "read_config: IPv6 parse error");
+			return -1;
+		}
+		*q = '\0';
+		q++;
+
+		if (q[0] == ':') {
+			q++;
+		}
+
+		/* Check to see if we have '[IPv6]:port:secret' syntax */
+		if((s=strchr(q, ':')) != NULL) {
+			*s = '\0';
+			s++;
+			serv->secret[serv->max] = strdup(s);
+			if (serv->secret[serv->max] == NULL) {
+				rc_log(LOG_CRIT, "read_config: out of memory");
+				if (option->val == NULL) {
+					free(p_dupe);
+					free(serv);
+				}
+				return -1;
+			}
+		}
+
+	} else /* Check to see if we have 'servername:port' syntax */
+	if ((q = strchr(p_pointer,':')) != NULL) {
+		*q = '\0';
+		q++;
+
+		/* Check to see if we have 'servername:port:secret' syntax */
+		if((s = strchr(q,':')) != NULL) {
+			*s = '\0';
+			s++;
+			serv->secret[serv->max] = strdup(s);
+			if (serv->secret[serv->max] == NULL) {
+				rc_log(LOG_CRIT, "read_config: out of memory");
+				if (option->val == NULL) {
+					free(p_dupe);
+					free(serv);
+				}
+				return -1;
+			}
+		}
+	}
+
+	if(q && strlen(q) > 0) {
+		serv->port[serv->max] = atoi(q);
+	} else {
+		if (!strcmp(option->name,"authserver"))
+			if ((svp = getservbyname ("radius", "udp")) == NULL)
+				serv->port[serv->max] = PW_AUTH_UDP_PORT;
+			else
+				serv->port[serv->max] = ntohs ((unsigned int) svp->s_port);
+		else if (!strcmp(option->name, "acctserver"))
+			if ((svp = getservbyname ("radacct", "udp")) == NULL)
+				serv->port[serv->max] = PW_ACCT_UDP_PORT;
+			else
+				serv->port[serv->max] = ntohs ((unsigned int) svp->s_port);
+		else {
+			rc_log(LOG_ERR, "%s: line %d: no default port for %s", filename, line, option->name);
+			if (option->val == NULL) {
+				free(p_dupe);
+				free(serv);
+			}
+			return -1;
+		}
+	}
+
+	serv->name[serv->max] = strdup(p_pointer);
+	if (serv->name[serv->max] == NULL) {
+		rc_log(LOG_CRIT, "read_config: out of memory");
+		if (option->val == NULL) {
+			free(p_dupe);
+			free(serv);
+		}
+		return -1;
+	}
+	free(p_dupe);
+
+	serv->deadtime_ends[serv->max] = -1;
+	serv->max++;
+
+	if (option->val == NULL)
+		option->val = (void *)serv;
+#endif
+	return 0;
+
+}
+
+static int set_option_auo(char const *filename, int line, OPTION *option, char const *p)
+{
+#if 0
+	int *iptr;
+	char *p_dupe = NULL;
+	char *p_pointer = NULL;
+	char *p_save = NULL;
+
+	p_dupe = strdup(p);
+
+	if (p_dupe == NULL) {
+		rc_log(LOG_WARNING, "%s: line %d: bogus option value", filename, line);
+		return -1;
+	}
+
+	if ((iptr = malloc(sizeof(iptr))) == NULL) {
+			rc_log(LOG_CRIT, "read_config: out of memory");
+			free(p_dupe);
+			return -1;
+	}
+
+	*iptr = 0;
+	p_pointer = strtok_r(p_dupe, ", \t", &p_save);
+
+	if (!strncmp(p_pointer, "local", 5))
+			*iptr = AUTH_LOCAL_FST;
+	else if (!strncmp(p_pointer, "radius", 6))
+			*iptr = AUTH_RADIUS_FST;
+	else {
+		rc_log(LOG_ERR,"%s: auth_order: unknown keyword: %s", filename, p);
+		free(iptr);
+		free(p_dupe);
+		return -1;
+	}
+
+	p_pointer = strtok_r(NULL, ", \t", &p_save);
+
+	if (p_pointer && (*p_pointer != '\0')) {
+		if ((*iptr & AUTH_RADIUS_FST) && !strcmp(p_pointer, "local"))
+			*iptr = (*iptr) | AUTH_LOCAL_SND;
+		else if ((*iptr & AUTH_LOCAL_FST) && !strcmp(p_pointer, "radius"))
+			*iptr = (*iptr) | AUTH_RADIUS_SND;
+		else {
+			rc_log(LOG_ERR,"%s: auth_order: unknown or unexpected keyword: %s", filename, p);
+			free(iptr);
+			free(p_dupe);
+			return -1;
+		}
+	}
+
+	option->val = (void *) iptr;
+
+	free(p_dupe);
+	return 0;
+#endif
+}
+
+/** Allow a config option to be added to rc_handle from inside a program
+ *
+ * @param rh a handle to parsed configuration.
+ * @param option_name the name of the option.
+ * @param option_val the value to be added.
+ * @param source typically should be %__FILE__ or %__func__ for logging purposes.
+ * @param line %__LINE__ for logging purposes.
+ * @return 0 on success, -1 on failure.
+ */
+int rc_add_config(rc_handle *rh, char const *option_name, char const *option_val, char const *source, int line)
+{
+	OPTION *option;
+
+	if ((option = find_option(rh, option_name, OT_ANY)) == NULL)
+	{
+		rc_log(LOG_ERR, "ERROR: unrecognized option: %s", option_name);
+		return -1;
+	}
+
+	if (option->status != ST_UNDEF)
+	{
+		rc_log(LOG_ERR, "ERROR: duplicate option: %s", option_name);
+		return -1;
+	}
+
+	switch (option->type) {
+		case OT_STR:
+			if (set_option_str(source, line, option, option_val) < 0) {
+				return -1;
+			}
+			break;
+		case OT_INT:
+			if (set_option_int(source, line, option, option_val) < 0) {
+				return -1;
+			}
+			break;
+		case OT_SRV:
+			if (set_option_srv(source, line, option, option_val) < 0) {
+				return -1;
+			}
+			break;
+		case OT_AUO:
+			if (set_option_auo(source, line, option, option_val) < 0) {
+				return -1;
+			}
+			break;
+		default:
+			rc_log(LOG_CRIT, "rc_add_config: impossible case branch!");
+			abort();
+	}
+
+	if (strcmp(option->name, "bindaddr") == 0) {
+		memset(&rh->own_bind_addr, 0, sizeof(rh->own_bind_addr));
+		rh->own_bind_addr_set = 0;
+		rc_own_bind_addr(rh, &rh->own_bind_addr);
+		rh->own_bind_addr_set = 1;
+	}
+
+	return 0;
+}
+
+/** Initialise a configuration structure
+ *
+ * Initialize the configuration structure from an external program.  For use when not
+ * running a standalone client that reads from a config file.
+ *
+ * @param rh a handle to parsed configuration.
+ * @return rc_handle on success, NULL on failure.
+ */
+rc_handle *rc_config_init(rc_handle *rh)
+{
+	int i;
+	SERVER *authservers;
+	SERVER *acctservers;
+	OPTION *acct;
+	OPTION *auth;
+
+        rh->config_options = malloc(sizeof(config_options_default));
+        if (rh->config_options == NULL)
+	{
+                rc_log(LOG_CRIT, "rc_config_init: out of memory");
+		rc_destroy(rh);
+                return NULL;
+        }
+        memcpy(rh->config_options, &config_options_default, sizeof(config_options_default));
+
+	acct = find_option(rh, "acctserver", OT_ANY);
+	auth = find_option(rh, "authserver", OT_ANY);
+	authservers = malloc(sizeof(SERVER));
+	acctservers = malloc(sizeof(SERVER));
+
+	if(authservers == NULL || acctservers == NULL)
+	{
+                rc_log(LOG_CRIT, "rc_config_init: error initializing server structs");
+		rc_destroy(rh);
+		if(authservers) free(authservers);
+		if(acctservers) free(acctservers);
+                return NULL;
+	}
+
+
+	authservers->max = 0;
+	acctservers->max = 0;
+
+	for(i=0; i < SERVER_MAX; i++)
+	{
+		authservers->name[i] = NULL;
+		authservers->secret[i] = NULL;
+		acctservers->name[i] = NULL;
+		acctservers->secret[i] = NULL;
+	}
+	acct->val = acctservers;
+	auth->val = authservers;
+	return rh;
+}
+
+/** Read the global config file
+ *
+ * @param filename a name of a file.
+ * @return new rc_handle on success, NULL when failure.
+ */
+void rc_read_config(rc_handle* rh)
+{
+    rh->config_options = &rcOptions;
+    
+    //memcpy(rh->config_options, &config_options_default, sizeof(config_options_default));
+}
+
+#if 0
+rc_handle *rc_read_config(char const *filename)
+{
+	FILE *configfd;
+	char buffer[512], *p;
+	OPTION *option;
+	int line;
+	size_t pos;
+	rc_handle *rh;
+
+	srandom((unsigned int)(time(NULL)+getpid()));
+
+	rh = rc_new();
+	if (rh == NULL)
+		return NULL;
+
+        rh->config_options = malloc(sizeof(config_options_default));
+        if (rh->config_options == NULL) {
+            rc_log(LOG_CRIT, "rc_read_config: out of memory");
+            rc_destroy(rh);
+            return NULL;
+        }
+        memcpy(rh->config_options, &config_options_default, sizeof(config_options_default));
+
+	if ((configfd = fopen(filename,"r")) == NULL)
+	{
+		rc_log(LOG_ERR,"rc_read_config: can't open %s: %s", filename, strerror(errno));
+		rc_destroy(rh);
+		return NULL;
+	}
+
+	line = 0;
+	while ((fgets(buffer, sizeof(buffer), configfd) != NULL))
+	{
+		line++;
+		p = buffer;
+
+		if ((*p == '\n') || (*p == '#') || (*p == '\0'))
+			continue;
+
+		p[strlen(p)-1] = '\0';
+
+
+		if ((pos = strcspn(p, "\t ")) == 0) {
+			rc_log(LOG_ERR, "%s: line %d: bogus format: %s", filename, line, p);
+			fclose(configfd);
+			rc_destroy(rh);
+			return NULL;
+		}
+
+		p[pos] = '\0';
+
+		if ((option = find_option(rh, p, OT_ANY)) == NULL) {
+			rc_log(LOG_ERR, "%s: line %d: unrecognized keyword: %s", filename, line, p);
+			fclose(configfd);
+			rc_destroy(rh);
+			return NULL;
+		}
+
+		if (option->status != ST_UNDEF) {
+			rc_log(LOG_ERR, "%s: line %d: duplicate option line: %s", filename, line, p);
+			fclose(configfd);
+			rc_destroy(rh);
+			return NULL;
+		}
+
+		p += pos+1;
+		while (isspace(*p))
+			p++;
+		pos = strlen(p) - 1;
+		while(pos != 0 && isspace(p[pos]))
+			pos--;
+		p[pos + 1] = '\0';
+
+		switch (option->type) {
+			case OT_STR:
+				if (set_option_str(filename, line, option, p) < 0) {
+					fclose(configfd);
+					rc_destroy(rh);
+				 	return NULL;
+				}
+				break;
+			case OT_INT:
+				if (set_option_int(filename, line, option, p) < 0) {
+					fclose(configfd);
+					rc_destroy(rh);
+				 	return NULL;
+				}
+				break;
+			case OT_SRV:
+				if (set_option_srv(filename, line, option, p) < 0) {
+					fclose(configfd);
+					rc_destroy(rh);
+				 	return NULL;
+				}
+				break;
+			case OT_AUO:
+				if (set_option_auo(filename, line, option, p) < 0) {
+					fclose(configfd);
+					rc_destroy(rh);
+				 	return NULL;
+				}
+				break;
+			default:
+				rc_log(LOG_CRIT, "rc_read_config: impossible case branch!");
+				abort();
+		}
+	}
+	fclose(configfd);
+
+	if (test_config(rh, filename) == -1) {
+		rc_destroy(rh);
+		return NULL;
+	}
+	return rh;
+}
+#endif
+
+/** Get the value of a config option
+ *
+ * @param rh a handle to parsed configuration.
+ * @param optname the name of an option.
+ * @return config option value.
+ */
+char *rc_conf_str(rc_handle const *rh, char const *optname)
+{
+	OPTION *option;
+
+	option = find_option(rh, optname, OT_STR);
+
+	if (option != NULL) {
+		return (char *)option->val;
+	} else {
+		rc_log(LOG_CRIT, "rc_conf_str: unkown config option requested: %s", optname);
+		return NULL;
+	}
+}
+
+/** Get the value of a config option
+ *
+ * @param rh a handle to parsed configuration.
+ * @param optname the name of an option.
+ * @return config option value.
+ */
+int rc_conf_int(rc_handle const *rh, char const *optname)
+{
+	OPTION *option;
+
+	option = find_option(rh, optname, OT_INT|OT_AUO);
+
+	if (option != NULL) {
+		if (option->val) {
+			return *((int *)option->val);
+		} else {
+			rc_log(LOG_ERR, "rc_conf_int: config option %s was not set", optname);
+			return 0;
+		}
+	} else {
+		rc_log(LOG_CRIT, "rc_conf_int: unkown config option requested: %s", optname);
+		return 0;
+	}
+}
+
+/** Get the value of a config option
+ *
+ * @param rh a handle to parsed configuration.
+ * @param optname the name of an option.
+ * @return config option value.
+ */
+SERVER *rc_conf_srv(rc_handle const *rh, char const *optname)
+{
+	OPTION *option;
+
+	option = find_option(rh, optname, OT_SRV);
+
+	if (option != NULL) {
+		return (SERVER *)option->val;
+	} else {
+		rc_log(LOG_CRIT, "rc_conf_srv: unkown config option requested: %s", optname);
+		return NULL;
+	}
+}
+
+/** Tests the configuration the user supplied
+ *
+ * @param rh a handle to parsed configuration.
+ * @param filename a name of a configuration file.
+ * @return 0 on success, -1 when failure.
+ */
+int test_config(rc_handle const *rh, char const *filename)
+{
+	SERVER *srv;
+
+	srv = rc_conf_srv(rh, "authserver");
+	if (!srv || !srv->max)
+	{
+		rc_log(LOG_ERR,"%s: no authserver specified", filename);
+		return -1;
+	}
+
+	srv = rc_conf_srv(rh, "acctserver");
+	if (!srv || !srv->max)
+	{
+		rc_log(LOG_ERR,"%s: no acctserver specified", filename);
+		return -1;
+	}
+	if (!rc_conf_str(rh, "servers"))
+	{
+		rc_log(LOG_ERR,"%s: no servers file specified", filename);
+		return -1;
+	}
+	if (!rc_conf_str(rh, "dictionary"))
+	{
+		rc_log(LOG_ERR,"%s: no dictionary specified", filename);
+		return -1;
+	}
+
+	if (rc_conf_int(rh, "radius_timeout") <= 0)
+	{
+		rc_log(LOG_ERR,"%s: radius_timeout <= 0 is illegal", filename);
+		return -1;
+	}
+	if (rc_conf_int(rh, "radius_retries") <= 0)
+	{
+		rc_log(LOG_ERR,"%s: radius_retries <= 0 is illegal", filename);
+		return -1;
+	}
+	if (rc_conf_int(rh, "radius_deadtime") < 0)
+	{
+		rc_log(LOG_ERR,"%s: radius_deadtime is illegal", filename);
+		return -1;
+	}
+	if (rc_conf_int(rh, "login_tries") <= 0)
+	{
+		rc_log(LOG_ERR,"%s: login_tries <= 0 is illegal", filename);
+		return -1;
+	}
+	if (rc_conf_int(rh, "login_timeout") <= 0)
+	{
+		rc_log(LOG_ERR,"%s: login_timeout <= 0 is illegal", filename);
+		return -1;
+	}
+	if (rc_conf_str(rh, "mapfile") == NULL)
+	{
+		rc_log(LOG_ERR,"%s: mapfile not specified", filename);
+		return -1;
+	}
+	if (rc_conf_str(rh, "nologin") == NULL)
+	{
+		rc_log(LOG_ERR,"%s: nologin not specified", filename);
+		return -1;
+	}
+
+	return 0;
+}
+
+/** See if info matches hostname
+ *
+ * @param info a struct addrinfo
+ * @param hostname the name of the host.
+ * @return 0 on success, -1 when failure.
+ */
+static int find_match (const struct addrinfo* addr, const struct addrinfo *hostname)
+{
+#if 0  
+	const struct addrinfo *ptr, *ptr2;
+	unsigned len1, len2;
+
+	ptr = addr;
+	while(ptr) {
+		ptr2 = hostname;
+		while(ptr2) {
+			len1 = SA_GET_INLEN(ptr->ai_addr);
+			len2 = SA_GET_INLEN(ptr2->ai_addr);
+
+			if (len1 > 0 && 
+			    len1 == len2 && 
+			    memcmp(SA_GET_INADDR(ptr->ai_addr), SA_GET_INADDR(ptr2->ai_addr), len1) == 0) {
+				return 0;
+			}
+			ptr2 = ptr2->ai_next;
+ 		}
+		ptr = ptr->ai_next;
+ 	}
+#endif    
+ 	return -1;
+}
+
+/** Checks if provided address is local address
+ *
+ * @param addr an %AF_INET or %AF_INET6 address
+ * @return 0 if local, 1 if not local, -1 on failure.
+ */
+static int rc_ipaddr_local(const struct sockaddr *addr)
+{
+#if 0  
+	int temp_sock, res, serrno;
+	struct sockaddr tmpaddr;
+
+	memcpy(&tmpaddr, addr, SA_LEN(addr));
+
+	temp_sock = socket(addr->sa_family, SOCK_DGRAM, 0);
+	if (temp_sock == -1)
+		return -1;
+
+	if (addr->sa_family == AF_INET) {
+		((struct sockaddr_in*)&tmpaddr)->sin_port = 0;
+	} else {
+		((struct sockaddr_in6*)&tmpaddr)->sin6_port = 0;
+	}
+	res = bind(temp_sock, &tmpaddr, SA_LEN(&tmpaddr));
+	serrno = errno;
+	close(temp_sock);
+	if (res == 0)
+		return 0;
+	if (serrno == EADDRNOTAVAIL)
+		return 1;
+#endif    
+	return -1;
+}
+
+/** Checks if provided name refers to ourselves
+ *
+ * @param info an addrinfo of the host to check
+ * @return 0 if yes, 1 if no and -1 on failure.
+ */
+static int rc_is_myname(const struct addrinfo *info)
+{
+#if 0  
+	const struct addrinfo *p;
+	int	res;
+
+	p = info;
+	while(p != NULL) {
+		res = rc_ipaddr_local(p->ai_addr);
+		if (res == 0 || res == -1) {
+ 			return res;
+		}
+		p = p->ai_next;
+ 	}
+#endif    
+ 	return 1;
+}
+
+/** Locate a server in the rh config or if not found, check for a servers file
+ *
+ * @param rh a handle to parsed configuration.
+ * @param server_name the name of the server.
+ * @param info: will hold a pointer to addrinfo
+ * @param secret will hold the server's secret (of %MAX_SECRET_LENGTH).
+ * @param flags %AUTH or %ACCT
+ 
+ * @return 0 on success, -1 on failure.
+ */
+//int rc_find_server_addr(rc_handle const *, char const *, struct addrinfo **, char *, unsigned flags);
+
+int rc_find_server_addr(rc_handle const *rh, char const *server_name,
+                        struct addrinfo** info, char *secret, unsigned flags)
+{
+#if 0
+	int		i;
+	int             result = 0;
+	FILE           *clientfd;
+	char           *h;
+	char           *s;
+	char            buffer[128];
+	char            hostnm[AUTH_ID_LEN + 1];
+	char	       *buffer_save;
+	char	       *hostnm_save;
+	SERVER	       *authservers;
+	SERVER	       *acctservers;
+	struct addrinfo *tmpinfo = NULL;
+
+	/* Lookup the IP address of the radius server */
+	if ((*info = rc_getaddrinfo (server_name, flags==AUTH?PW_AI_AUTH:PW_AI_ACCT)) == NULL)
+		return -1;
+
+	if (flags == AUTH) {
+		/* Check to see if the server secret is defined in the rh config */
+		if( (authservers = rc_conf_srv(rh, "authserver")) != NULL )
+		{
+			for( i = 0; i < authservers->max; i++ )
+			{
+				if( (strncmp(server_name, authservers->name[i], strlen(server_name)) == 0) &&
+				    (authservers->secret[i] != NULL) )
+				{
+					memset (secret, '\0', MAX_SECRET_LENGTH);
+					strlcpy (secret, authservers->secret[i], MAX_SECRET_LENGTH);
+					return 0;
+				}
+			}
+		}
+	} else if (flags == ACCT) {
+		if( (acctservers = rc_conf_srv(rh, "acctserver")) != NULL )
+		{
+			for( i = 0; i < acctservers->max; i++ )
+			{
+				if( (strncmp(server_name, acctservers->name[i], strlen(server_name)) == 0) &&
+				    (acctservers->secret[i] != NULL) )
+				{
+					memset (secret, '\0', MAX_SECRET_LENGTH);
+					strlcpy (secret, acctservers->secret[i], MAX_SECRET_LENGTH);
+					return 0;
+				}
+			}
+		}
+	}
+
+	/* We didn't find it in the rh_config or the servername is too long so look for a
+	 * servers file to define the secret(s)
+	 */
+
+	if ((clientfd = fopen (rc_conf_str(rh, "servers"), "r")) == NULL)
+	{
+		rc_log(LOG_ERR, "rc_find_server: couldn't open file: %s: %s", strerror(errno), rc_conf_str(rh, "servers"));
+		goto fail;
+	}
+
+	while (fgets (buffer, sizeof (buffer), clientfd) != NULL)
+	{
+		if (*buffer == '#')
+			continue;
+
+		if ((h = strtok_r(buffer, " \t\n", &buffer_save)) == NULL) /* first hostname */
+			continue;
+
+		strlcpy (hostnm, h, AUTH_ID_LEN);
+
+		if ((s = strtok_r (NULL, " \t\n", &buffer_save)) == NULL) /* and secret field */
+			continue;
+
+		strlcpy (secret, s, MAX_SECRET_LENGTH);
+
+		if (!strchr (hostnm, '/')) /* If single name form */
+		{
+			tmpinfo = rc_getaddrinfo(hostnm, 0);
+			if (tmpinfo)
+			{
+				result = find_match (*info, tmpinfo);
+				if (result == 0)
+				{
+					result++;
+					break;
+				}
+
+				//freeaddrinfo(tmpinfo);
+				tmpinfo = NULL;
+			}
+		}
+		else /* <name1>/<name2> "paired" form */
+		{
+			strtok_r(hostnm, "/", &hostnm_save);
+			tmpinfo = rc_getaddrinfo(hostnm, 0);
+			if (tmpinfo)
+			{
+				if (rc_is_myname(tmpinfo) == 0)
+				{	     /* If we're the 1st name, target is 2nd */
+					if (find_match (*info, tmpinfo) == 0)
+					{
+						result++;
+						break;
+					}
+				}
+				else	/* If we were 2nd name, target is 1st name */
+				{
+					if (find_match (*info, tmpinfo) == 0)
+					{
+						result++;
+						break;
+					}
+				}
+				//freeaddrinfo(tmpinfo);
+				tmpinfo = NULL;
+			}
+		}
+	}
+	fclose (clientfd);
+	if (result == 0)
+	{
+		memset (buffer, '\0', sizeof (buffer));
+		memset (secret, '\0', MAX_SECRET_LENGTH);
+		rc_log(LOG_ERR, "rc_find_server: couldn't find RADIUS server %s in %s",
+			 server_name, rc_conf_str(rh, "servers"));
+		goto fail;
+	}
+	
+	result = 0;
+	goto cleanup;
+
+ fail:
+ 	//freeaddrinfo(*info);
+ 	result = -1;
+
+ cleanup:
+ 	//if (tmpinfo)
+ 		//freeaddrinfo(tmpinfo);
+
+	return result;
+#endif
+}
+
+/**
+ * rc_config_free:
+ * @param rh a handle to parsed configuration
+ *
+ * Free allocated config values
+ *
+ */
+
+void
+rc_config_free(rc_handle *rh)
+{
+	int i, j;
+	SERVER *serv;
+
+	if (rh->config_options == NULL)
+		return;
+
+	for (i = 0; i < NUM_OPTIONS; i++) {
+		if (rh->config_options[i].val == NULL)
+			continue;
+		if (rh->config_options[i].type == OT_SRV) {
+		        serv = (SERVER *)rh->config_options[i].val;
+			for (j = 0; j < serv->max; j++){
+				free(serv->name[j]);
+				if(serv->secret[j]) free(serv->secret[j]);
+			}
+			free(serv);
+		} else {
+			free(rh->config_options[i].val);
+		}
+	}
+	free(rh->config_options);
+	rh->config_options = NULL;
+}

+ 504 - 0
thirdparty/FreeRadius/lib/dict.c

@@ -0,0 +1,504 @@
+/*
+ * $Id: dict.c,v 1.10 2007/07/11 17:29:29 cparker Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#if defined ( __GNUC__ )
+#include <my_strings.h>
+#endif
+
+/** Initialize the dictionary
+ *
+ * Read all ATTRIBUTES into the dictionary_attributes list.
+ * Read all VALUES into the dictionary_values list.
+ *
+ * @param rh a handle to parsed configuration.
+ * @param filename the name of the dictionary file.
+ * @return 0 on success, -1 on failure.
+ */
+int rc_read_dictionary (rc_handle *rh, char const *filename)
+{
+	FILE           *dictfd;
+	char            dummystr[AUTH_ID_LEN];
+	char            namestr[AUTH_ID_LEN];
+	char            valstr[AUTH_ID_LEN];
+	char            attrstr[AUTH_ID_LEN];
+	char            typestr[AUTH_ID_LEN];
+	char		optstr[AUTH_ID_LEN];
+	char		*cp, *ifilename;
+	int             line_no;
+	DICT_ATTR      *attr;
+	DICT_VALUE     *dval;
+	DICT_VENDOR    *dvend;
+	char            buffer[256];
+	int             value;
+	int             type;
+	unsigned attr_vendorspec = 0;
+
+	if ((dictfd = fopen (filename, "r")) == NULL)
+	{
+		rc_log(LOG_ERR, "rc_read_dictionary couldn't open dictionary %s: %s",
+				filename, strerror(errno));
+		return -1;
+	}
+
+	line_no = 0;
+	while (fgets (buffer, sizeof (buffer), dictfd) != NULL)
+	{
+		line_no++;
+
+		/* Skip empty space */
+		if (*buffer == '#' || *buffer == '\0' || *buffer == '\n' || \
+		    *buffer == '\r')
+		{
+			continue;
+		}
+
+		/* Strip out comments */
+		cp = strchr(buffer, '#');
+		if (cp != NULL)
+		{
+			*cp = '\0';
+		}
+
+		if (strncmp (buffer, "ATTRIBUTE", 9) == 0)
+		{
+			optstr[0] = '\0';
+			/* Read the ATTRIBUTE line */
+			if (sscanf (buffer, "%63s%63s%63s%63s%63s", dummystr, namestr,
+				    valstr, typestr, optstr) < 4)
+			{
+				rc_log(LOG_ERR, "rc_read_dictionary: invalid attribute on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			/*
+			 * Validate all entries
+			 */
+			if (strlen (namestr) > NAME_LENGTH)
+			{
+				rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			if (!isdigit (*valstr))
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid value on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+			value = atoi (valstr);
+
+			if (strcmp (typestr, "string") == 0)
+			{
+				type = PW_TYPE_STRING;
+			}
+			else if (strcmp (typestr, "integer") == 0)
+			{
+				type = PW_TYPE_INTEGER;
+			}
+			else if (strcmp (typestr, "ipaddr") == 0)
+			{
+				type = PW_TYPE_IPADDR;
+			}
+			else if (strcmp (typestr, "ipv6addr") == 0)
+			{
+				type = PW_TYPE_IPV6ADDR;
+			}
+			else if (strcmp (typestr, "ipv6prefix") == 0)
+			{
+				type = PW_TYPE_IPV6PREFIX;
+			}
+			else if (strcmp (typestr, "date") == 0)
+			{
+				type = PW_TYPE_DATE;
+			}
+			else
+			{
+				rc_log(LOG_ERR,
+				  "rc_read_dictionary: invalid type on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			dvend = NULL;
+			if (optstr[0] != '\0') {
+				char *cp1;
+				for (cp1 = optstr; cp1 != NULL; cp1 = cp) {
+					cp = strchr(cp1, ',');
+					if (cp != NULL) {
+						*cp = '\0';
+						cp++;
+					}
+					if (strncmp(cp1, "vendor=", 7) == 0)
+						cp1 += 7;
+					dvend = rc_dict_findvend(rh, cp1);
+					if (dvend == NULL) {
+						rc_log(LOG_ERR,
+						 "rc_read_dictionary: unknown Vendor-Id %s on line %d of dictionary %s",
+							 cp1, line_no, filename);
+						fclose(dictfd);
+						return -1;
+					}
+				}
+			}
+
+			/* Create a new attribute for the list */
+			if ((attr = malloc (sizeof (DICT_ATTR))) == NULL)
+			{
+				rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+				fclose(dictfd);
+				return -1;
+			}
+			strcpy (attr->name, namestr);
+			attr->value = value | (attr_vendorspec << 16);
+			attr->type = type;
+
+			if (dvend != NULL) {
+				attr->value = value | (dvend->vendorpec << 16);
+			} else {
+				attr->value = value | (attr_vendorspec << 16);
+			}
+
+			/* Insert it into the list */
+			attr->next = rh->dictionary_attributes;
+			rh->dictionary_attributes = attr;
+		}
+		else if (strncmp (buffer, "VALUE", 5) == 0)
+		{
+			/* Read the VALUE line */
+			if (sscanf (buffer, "%63s%63s%63s%63s", dummystr, attrstr,
+				    namestr, valstr) != 4)
+			{
+				rc_log(LOG_ERR,
+			   "rc_read_dictionary: invalid value entry on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			/*
+			 * Validate all entries
+			 */
+			if (strlen (attrstr) > NAME_LENGTH)
+			{
+				rc_log(LOG_ERR,
+		      "rc_read_dictionary: invalid attribute length on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			if (strlen (namestr) > NAME_LENGTH)
+			{
+				rc_log(LOG_ERR,
+			   "rc_read_dictionary: invalid name length on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			if (!isdigit (*valstr))
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid value on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+			value = atoi (valstr);
+
+			/* Create a new VALUE entry for the list */
+			if ((dval = malloc (sizeof (DICT_VALUE))) == NULL)
+			{
+				rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+				fclose(dictfd);
+				return -1;
+			}
+			strcpy (dval->attrname, attrstr);
+			strcpy (dval->name, namestr);
+			dval->value = value;
+
+			/* Insert it into the list */
+			dval->next = rh->dictionary_values;
+			rh->dictionary_values = dval;
+		}
+                else if (strncmp (buffer, "$INCLUDE", 8) == 0)
+                {
+			/* Read the $INCLUDE line */
+			if (sscanf (buffer, "%63s%63s", dummystr, namestr) != 2)
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid include entry on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+			ifilename = namestr;
+			/* Append directory if necessary */
+			if (namestr[0] != '/') {
+				cp = strrchr(filename, '/');
+				if (cp != NULL) {
+					ifilename = malloc(AUTH_ID_LEN);
+					*cp = '\0';
+					snprintf(ifilename, AUTH_ID_LEN, "%s/%s", filename, namestr);
+					*cp = '/';
+				}
+			}
+			if (rc_read_dictionary(rh, ifilename) < 0)
+			{
+				fclose(dictfd);
+				return -1;
+			}
+		}
+		else if (strncmp (buffer, "END-VENDOR", 10) == 0)
+		{
+			attr_vendorspec = 0;
+		}
+		else if (strncmp (buffer, "BEGIN-VENDOR", 12) == 0)
+		{
+			DICT_VENDOR *v;
+			/* Read the vendor name */
+			if (sscanf (buffer+12, "%63s", dummystr) != 1)
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid Vendor-Id on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			v = rc_dict_findvend(rh, dummystr);
+			if (v == NULL) {
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: unknown Vendor %s on line %d of dictionary %s",
+					 dummystr, line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			attr_vendorspec = v->vendorpec;
+		}
+		else if (strncmp (buffer, "VENDOR", 6) == 0)
+		{
+			/* Read the VALUE line */
+			if (sscanf (buffer, "%63s%63s%63s", dummystr, attrstr, valstr) != 3)
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid Vendor-Id on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			/* Validate all entries */
+			if (strlen (attrstr) > NAME_LENGTH)
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid attribute length on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+
+			if (!isdigit (*valstr))
+			{
+				rc_log(LOG_ERR,
+				 "rc_read_dictionary: invalid Vendor-Id on line %d of dictionary %s",
+					 line_no, filename);
+				fclose(dictfd);
+				return -1;
+			}
+			value = atoi (valstr);
+
+			/* Create a new VENDOR entry for the list */
+			dvend = malloc(sizeof(DICT_VENDOR));
+			if (dvend == NULL)
+			{
+				rc_log(LOG_CRIT, "rc_read_dictionary: out of memory");
+				fclose(dictfd);
+				return -1;
+			}
+			strcpy (dvend->vendorname, attrstr);
+			dvend->vendorpec = value;
+
+			/* Insert it into the list */
+			dvend->next = rh->dictionary_vendors;
+			rh->dictionary_vendors = dvend;
+                }
+	}
+	fclose (dictfd);
+	return 0;
+}
+
+/** Lookup a DICT_ATTR by attribute number
+ *
+ * @param rh a handle to parsed configuration.
+ * @param attribute the attribute ID.
+ * @return the full attribute structure based on the attribute id number.
+ */
+DICT_ATTR *rc_dict_getattr(rc_handle const *rh, int attribute)
+{
+	DICT_ATTR      *attr;
+
+	attr = rh->dictionary_attributes;
+	while (attr != NULL)
+	{
+		if (attr->value == attribute)
+		{
+			return attr;
+		}
+		attr = attr->next;
+	}
+	return NULL;
+}
+
+/** Lookup a DICT_ATTR by its name
+ *
+ * @param rh a handle to parsed configuration.
+ * @param attrname the attribute name.
+ *
+ * @return the full attribute structure based on the attribute name.
+ */
+DICT_ATTR *rc_dict_findattr(rc_handle const *rh, char const *attrname)
+{
+	DICT_ATTR      *attr;
+
+	attr = rh->dictionary_attributes;
+	while (attr != NULL)
+	{
+		if (strcasecmp (attr->name, attrname) == 0)
+		{
+			return attr;
+		}
+		attr = attr->next;
+	}
+	return NULL;
+}
+
+
+/** Lookup a DICT_VALUE by its name
+ *
+ * @param rh a handle to parsed configuration.
+ * @param valname the value name.
+ * @return the full value structure based on the value name.
+ */
+DICT_VALUE *rc_dict_findval(rc_handle const *rh, char const *valname)
+{
+	DICT_VALUE     *val;
+
+	val = rh->dictionary_values;
+	while (val != NULL)
+	{
+		if (strcasecmp (val->name, valname) == 0)
+		{
+			return val;
+		}
+		val = val->next;
+	}
+	return NULL;
+}
+
+/** Lookup a DICT_VENDOR by its name
+ *
+ * @param rh a handle to parsed configuration.
+ * @param valname the vendor name.
+ * @return the full vendor structure based on the vendor name.
+ */
+DICT_VENDOR *rc_dict_findvend(rc_handle const *rh, char const *vendorname)
+{
+	DICT_VENDOR	*vend;
+
+	for (vend = rh->dictionary_vendors; vend != NULL; vend = vend->next)
+		if (strcasecmp(vend->vendorname, vendorname) == 0)
+			return vend;
+	return NULL;
+}
+
+/** Lookup a DICT_VENDOR by its IANA number
+ *
+ * @param rh a handle to parsed configuration.
+ * @param vendorpec the vendor ID.
+ * @return the full vendor structure based on the vendor id number.
+ */
+DICT_VENDOR *rc_dict_getvend (rc_handle const *rh, int vendorpec)
+{
+        DICT_VENDOR      *vend;
+
+	for (vend = rh->dictionary_vendors; vend != NULL; vend = vend->next)
+		if (vend->vendorpec == vendorpec)
+			return vend;
+	return NULL;
+}
+
+/** Get DICT_VALUE based on attribute name and integer value number
+ *
+ * @param rh a handle to parsed configuration.
+ * @param value the attribute value.
+ * @param attrname the attribute name.
+ * @return the full value structure based on the actual value and the associated attribute name.
+ */
+DICT_VALUE *rc_dict_getval(rc_handle const *rh, uint32_t value, char const *attrname)
+{
+	DICT_VALUE     *val;
+
+	val = rh->dictionary_values;
+	while (val != NULL)
+	{
+		if (strcmp (val->attrname, attrname) == 0 &&
+				val->value == value)
+		{
+			return val;
+		}
+		val = val->next;
+	}
+	return NULL;
+}
+
+/** Frees the allocated av lists
+ *
+ * @param rh a handle to parsed configuration.
+ */
+void rc_dict_free(rc_handle *rh)
+{
+	DICT_ATTR	*attr, *nattr;
+	DICT_VALUE	*val, *nval;
+	DICT_VENDOR	*vend, *nvend;
+
+	for (attr = rh->dictionary_attributes; attr != NULL; attr = nattr) {
+		nattr = attr->next;
+		free(attr);
+	}
+	for (val = rh->dictionary_values; val != NULL; val = nval) {
+		nval = val->next;
+		free(val);
+	}
+	for (vend = rh->dictionary_vendors; vend != NULL; vend = nvend) {
+		nvend = vend->next;
+		free(vend);
+	}
+	rh->dictionary_attributes = NULL;
+	rh->dictionary_values = NULL;
+	rh->dictionary_vendors = NULL;
+}

+ 49 - 0
thirdparty/FreeRadius/lib/fr_log.c

@@ -0,0 +1,49 @@
+/*
+ * $Id: log.c,v 1.5 2007/06/21 18:07:23 cparker Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+
+/** Opens system log
+ *
+ * @param ident the name of the program.
+ */
+void rc_openlog(char const *ident)
+{
+#ifndef _MSC_VER /* TODO: Fix me */
+//	openlog(ident, LOG_PID, RC_LOG_FACILITY);
+#endif
+}
+
+/** Logs information on system log
+ *
+ * @param prio the syslog priority.
+ * @param format the format of the data to print.
+ */
+void rc_log(int prio, char const *format, ...)
+{
+#ifdef RC_LOG  
+    printf(format);
+#endif    
+/*  
+	char buff[1024];
+	va_list ap;
+
+	va_start(ap,format);
+	vsnprintf(buff, sizeof(buff), format, ap);
+	va_end(ap);
+
+#ifndef _MSC_VER  TODO: Fix me 
+	syslog(prio, "%s", buff);
+#endif
+*/    
+}

+ 251 - 0
thirdparty/FreeRadius/lib/fr_md5.c

@@ -0,0 +1,251 @@
+#include "fr_md5.h"
+
+/*	The below was retrieved from
+ *	http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/crypto/md5.c?rev=1.1
+ *	with the following changes:
+ *	#includes commented out.
+ *	Support context->count as uint32_t[2] instead of uint64_t
+ *	u_int* to uint*
+ */
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.	This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+/*#include <sys/param.h>*/
+/*#include <sys/systm.h>*/
+/*#include <crypto/md5.h>*/
+
+#define PUT_64BIT_LE(cp, value) do {				\
+	(cp)[7] = (value)[1] >> 24;					\
+	(cp)[6] = (value)[1] >> 16;					\
+	(cp)[5] = (value)[1] >> 8;					\
+	(cp)[4] = (value)[1];						\
+	(cp)[3] = (value)[0] >> 24;					\
+	(cp)[2] = (value)[0] >> 16;					\
+	(cp)[1] = (value)[0] >> 8;					\
+	(cp)[0] = (value)[0]; } while (0)
+
+#define PUT_32BIT_LE(cp, value) do {					\
+	(cp)[3] = (value) >> 24;					\
+	(cp)[2] = (value) >> 16;					\
+	(cp)[1] = (value) >> 8;						\
+	(cp)[0] = (value); } while (0)
+
+static uint8_t PADDING[MD5_BLOCK_LENGTH] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+MD5Init(MD5_CTX *ctx)
+{
+	ctx->count[0] = 0;
+	ctx->count[1] = 0;
+	ctx->state[0] = 0x67452301;
+	ctx->state[1] = 0xefcdab89;
+	ctx->state[2] = 0x98badcfe;
+	ctx->state[3] = 0x10325476;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MD5Update(MD5_CTX *ctx, uint8_t const *input, size_t len)
+{
+	size_t have, need;
+
+	/* Check how many bytes we already have and how many more we need. */
+	have = (size_t)((ctx->count[0] >> 3) & (MD5_BLOCK_LENGTH - 1));
+	need = MD5_BLOCK_LENGTH - have;
+
+	/* Update bitcount */
+/*	ctx->count += (uint64_t)len << 3;*/
+	if ((ctx->count[0] += ((uint32_t)len << 3)) < (uint32_t)len) {
+	/* Overflowed ctx->count[0] */
+		ctx->count[1]++;
+	}
+	ctx->count[1] += ((uint32_t)len >> 29);
+
+
+
+	if (len >= need) {
+		if (have != 0) {
+			memcpy(ctx->buffer + have, input, need);
+			MD5Transform(ctx->state, ctx->buffer);
+			input += need;
+			len -= need;
+			have = 0;
+		}
+
+		/* Process data in MD5_BLOCK_LENGTH-byte chunks. */
+		while (len >= MD5_BLOCK_LENGTH) {
+			MD5Transform(ctx->state, input);
+			input += MD5_BLOCK_LENGTH;
+			len -= MD5_BLOCK_LENGTH;
+		}
+	}
+
+	/* Handle any remaining bytes of data. */
+	if (len != 0)
+		memcpy(ctx->buffer + have, input, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)
+{
+	uint8_t count[8];
+	size_t padlen;
+	int i;
+
+	/* Convert count to 8 bytes in little endian order. */
+	PUT_64BIT_LE(count, ctx->count);
+
+	/* Pad out to 56 mod 64. */
+	padlen = MD5_BLOCK_LENGTH -
+	    ((ctx->count[0] >> 3) & (MD5_BLOCK_LENGTH - 1));
+	if (padlen < 1 + 8)
+		padlen += MD5_BLOCK_LENGTH;
+	MD5Update(ctx, PADDING, padlen - 8);		/* padlen - 8 <= 64 */
+	MD5Update(ctx, count, 8);
+
+	if (digest != NULL) {
+		for (i = 0; i < 4; i++)
+			PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
+	}
+	memset(ctx, 0, sizeof(*ctx));	/* in case it's sensitive */
+}
+
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+MD5Transform(uint32_t state[4], uint8_t const block[MD5_BLOCK_LENGTH])
+{
+	uint32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
+
+	for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
+		in[a] = (uint32_t)(
+		    (uint32_t)(block[a * 4 + 0]) |
+		    (uint32_t)(block[a * 4 + 1]) <<  8 |
+		    (uint32_t)(block[a * 4 + 2]) << 16 |
+		    (uint32_t)(block[a * 4 + 3]) << 24);
+	}
+
+	a = state[0];
+	b = state[1];
+	c = state[2];
+	d = state[3];
+
+	MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478,  7);
+	MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
+	MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
+	MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
+	MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf,  7);
+	MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
+	MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
+	MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
+	MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8,  7);
+	MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
+	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122,  7);
+	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+	MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562,  5);
+	MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340,  9);
+	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+	MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
+	MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d,  5);
+	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453,  9);
+	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+	MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
+	MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6,  5);
+	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6,  9);
+	MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
+	MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
+	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
+	MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8,  9);
+	MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
+	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+	MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942,  4);
+	MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
+	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+	MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44,  4);
+	MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
+	MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
+	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
+	MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
+	MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
+	MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
+	MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039,  4);
+	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+	MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);
+
+	MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244,  6);
+	MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);
+	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+	MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);
+	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3,  6);
+	MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);
+	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+	MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);
+	MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f,  6);
+	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+	MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);
+	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+	MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82,  6);
+	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+	MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);
+	MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);
+
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+}

+ 86 - 0
thirdparty/FreeRadius/lib/fr_md5.h

@@ -0,0 +1,86 @@
+/*
+ * md5.h        Structures and prototypes for md5.
+ *
+ * Version:     $Id: md5.h,v 1.2 2007/06/21 18:07:24 cparker Exp $
+ * License:	BSD, but largely derived from a public domain source.
+ *
+ */
+
+#ifndef _RCRAD_MD5_H
+#define _RCRAD_MD5_H
+
+#include "radius_config.h"
+
+#ifdef HAVE_NETTLE
+
+#include <nettle/md5-compat.h>
+
+#else
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#include <string.h>
+/*
+ *  FreeRADIUS Client defines to ensure globally unique MD5 function names,
+ *  so that we don't pick up vendor-specific broken MD5 libraries.
+ */
+#define MD5_CTX		librad_MD5_CTX
+#define MD5Init		librad_MD5Init
+#define MD5Update	librad_MD5Update
+#define MD5Final	librad_MD5Final
+#define MD5Transform	librad_MD5Transform
+
+/*  The below was retrieved from
+ *  http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/crypto/md5.h?rev=1.1
+ *  With the following changes: uint64_t => uint32_t[2]
+ *  Commented out #include <sys/cdefs.h>
+ *  Commented out the __BEGIN and __END _DECLS, and the __attributes.
+ */
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ */
+
+#define	MD5_BLOCK_LENGTH		64
+#define	MD5_DIGEST_LENGTH		16
+
+typedef struct MD5Context {
+	uint32_t state[4];			//!< State.
+	uint32_t count[2];			//!< Number of bits, mod 2^64.
+	uint8_t buffer[MD5_BLOCK_LENGTH];	//!< Input buffer.
+} MD5_CTX;
+
+/* include <sys/cdefs.h> */
+
+/* __BEGIN_DECLS */
+void	 MD5Init(MD5_CTX *);
+void	 MD5Update(MD5_CTX *, uint8_t const *, size_t)
+/*		__attribute__((__bounded__(__string__,2,3)))*/;
+void	 MD5Final(uint8_t [MD5_DIGEST_LENGTH], MD5_CTX *)
+/*		__attribute__((__bounded__(__minbytes__,1,MD5_DIGEST_LENGTH)))*/;
+void	 MD5Transform(uint32_t [4], uint8_t const [MD5_BLOCK_LENGTH])
+/*		__attribute__((__bounded__(__minbytes__,1,4)))*/
+/*		__attribute__((__bounded__(__minbytes__,2,MD5_BLOCK_LENGTH)))*/;
+/* __END_DECLS */
+
+#endif /* HAVE_NETTLE */
+
+#endif /* _RCRAD_MD5_H */

+ 56 - 0
thirdparty/FreeRadius/lib/fr_options.h

@@ -0,0 +1,56 @@
+/*
+ * $Id: options.h,v 1.6 2008/03/05 16:35:20 cparker Exp $
+ *
+ * Copyright (C) 1996 Lars Fenneberg
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+#define OPTION_LEN	64
+
+/* ids for different option types */
+#define OT_STR		(1<<0)			//!< string.
+#define OT_INT		(1<<1)			//!< integer.
+#define OT_SRV		(1<<2)			//!< server list.
+#define OT_AUO		(1<<3)			//!< authentication order.
+
+#define OT_ANY		((unsigned int)~0)	//!< Used internally.
+
+/* status types */
+#define ST_UNDEF	(1<<0)			//!< option is undefined.
+
+typedef struct _option {
+	char name[OPTION_LEN];			//!< name of the option.
+	int type, status;			//!< type and status.
+	void *val;				//!< pointer to option value.
+} OPTION;
+
+static OPTION config_options_default[] = {
+/* internally used options */
+{"config_file",		OT_STR, ST_UNDEF, NULL},
+/* General options */
+{"auth_order",	 	OT_AUO, ST_UNDEF, NULL},
+{"login_tries",	 	OT_INT, ST_UNDEF, NULL},
+{"login_timeout",	OT_INT, ST_UNDEF, NULL},
+{"nologin",		OT_STR, ST_UNDEF, NULL},
+{"issue",		OT_STR, ST_UNDEF, NULL},
+/* RADIUS specific options */
+{"authserver",		OT_SRV, ST_UNDEF, NULL},
+{"acctserver",		OT_SRV, ST_UNDEF, NULL},
+{"servers",		OT_STR, ST_UNDEF, NULL},
+{"dictionary",		OT_STR, ST_UNDEF, NULL},
+{"login_radius",	OT_STR, ST_UNDEF, NULL},
+{"mapfile",		OT_STR, ST_UNDEF, NULL},
+{"default_realm",	OT_STR, ST_UNDEF, NULL},
+{"radius_timeout",	OT_INT, ST_UNDEF, NULL},
+{"radius_retries",	OT_INT,	ST_UNDEF, NULL},
+{"radius_deadtime",	OT_INT, ST_UNDEF, NULL},
+{"bindaddr",		OT_STR, ST_UNDEF, NULL},
+/* local options */
+{"login_local",		OT_STR, ST_UNDEF, NULL},
+};
+
+#define	NUM_OPTIONS	((sizeof(config_options_default))/(sizeof(config_options_default[0])))

+ 29 - 0
thirdparty/FreeRadius/lib/rc-md5.c

@@ -0,0 +1,29 @@
+/* MD5 message-digest algorithm */
+
+/* This file is licensed under the BSD License, but is largely derived from
+ * public domain source code
+ */
+
+/*
+ *  FORCE MD5 TO USE OUR MD5 HEADER FILE!
+ *
+ *  If we don't do this, it might pick up the systems broken MD5.
+ */
+#include "rc-md5.h"
+
+/** Hash the provided data using MD5
+ *
+ * @param[out] output will hold a 16-byte checksum.
+ * @param[in] input pointer to data to hash.
+ * @param[in] inlen the length of input.
+ */
+void rc_md5_calc(unsigned char *output, unsigned char const *input,
+		 size_t inlen)
+{
+	MD5_CTX	context;
+
+	MD5Init(&context);
+	MD5Update(&context, input, inlen);
+	MD5Final(output, &context);
+}
+

+ 28 - 0
thirdparty/FreeRadius/lib/rc-md5.h

@@ -0,0 +1,28 @@
+/*
+ * md5.h        Structures and prototypes for md5.
+ *
+ * Version:     $Id: md5.h,v 1.2 2007/06/21 18:07:24 cparker Exp $
+ * License:	BSD
+ *
+ */
+
+#ifndef _RC_MD5_H
+#define _RC_MD5_H
+
+#include "radius_config.h"
+#include <stdlib.h>
+
+#ifdef HAVE_NETTLE
+
+#include <nettle/md5-compat.h>
+
+#else
+
+#include "fr_md5.h"
+
+#endif /* HAVE_NETTLE */
+
+void rc_md5_calc(unsigned char *output, unsigned char const *input,
+		     size_t inputlen);
+
+#endif /* _RC_MD5_H */

+ 549 - 0
thirdparty/FreeRadius/lib/sendserver.c

@@ -0,0 +1,549 @@
+/*
+ * $Id: sendserver.c,v 1.30 2010/06/15 09:22:52 aland Exp $
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+//#include <poll.h>
+
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include <pathnames.h>
+#include "freeradius-client.h"
+#include "util.h"
+#include "radius_user.h"
+#include "parameters.h"
+
+#include "lwip/sockets.h"
+
+#define	SA(p)	((struct sockaddr *)(p))
+
+static void rc_random_vector (unsigned char *);
+static int rc_check_reply (AUTH_HDR *, int, char const *, unsigned char const *, unsigned char);
+
+/** Packs an attribute value pair list into a buffer
+ *
+ * @param vp a pointer to a #VALUE_PAIR.
+ * @param secret the secret used by the server.
+ * @param auth a pointer to #AUTH_HDR.
+ * @return The number of octets packed.
+ */
+static int rc_pack_list (VALUE_PAIR *vp, char *secret, AUTH_HDR *auth)
+{
+	int             length, i, pc, padded_length;
+	int             total_length = 0;
+	size_t			secretlen;
+	uint32_t           lvalue, vendor;
+	unsigned char   passbuf[MAX(AUTH_PASS_LEN, CHAP_VALUE_LENGTH)];
+	unsigned char   md5buf[256];
+	unsigned char   *buf, *vector, *vsa_length_ptr;
+
+	buf = auth->data;
+
+	while (vp != NULL)
+	{
+		vsa_length_ptr = NULL;
+		if (VENDOR(vp->attribute) != 0) {
+			*buf++ = PW_VENDOR_SPECIFIC;
+			vsa_length_ptr = buf;
+			*buf++ = 6;
+			vendor = htonl(VENDOR(vp->attribute));
+			memcpy(buf, &vendor, sizeof(uint32_t));
+			buf += 4;
+			total_length += 6;
+		}
+		*buf++ = (vp->attribute & 0xff);
+
+		switch (vp->attribute)
+		{
+		 case PW_USER_PASSWORD:
+
+		  /* Encrypt the password */
+
+		  /* Chop off password at AUTH_PASS_LEN */
+		  length = vp->lvalue;
+		  if (length > AUTH_PASS_LEN)
+			length = AUTH_PASS_LEN;
+
+		  /* Calculate the padded length */
+		  padded_length = (length+(AUTH_VECTOR_LEN-1)) & ~(AUTH_VECTOR_LEN-1);
+
+		  /* Record the attribute length */
+		  *buf++ = padded_length + 2;
+		  if (vsa_length_ptr != NULL) *vsa_length_ptr += padded_length + 2;
+
+		  /* Pad the password with zeros */
+		  memset ((char *) passbuf, '\0', AUTH_PASS_LEN);
+		  memcpy ((char *) passbuf, vp->strvalue, (size_t) length);
+
+		  secretlen = strlen (secret);
+		  vector = (unsigned char *)auth->vector;
+		  for(i = 0; i < padded_length; i += AUTH_VECTOR_LEN)
+		  {
+		  	/* Calculate the MD5 digest*/
+		  	strcpy ((char *) md5buf, secret);
+		  	memcpy ((char *) md5buf + secretlen, vector,
+		  		  AUTH_VECTOR_LEN);
+		  	rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN);
+
+		        /* Remeber the start of the digest */
+		  	vector = buf;
+
+			/* Xor the password into the MD5 digest */
+			for (pc = i; pc < (i + AUTH_VECTOR_LEN); pc++)
+		  	{
+				*buf++ ^= passbuf[pc];
+		  	}
+		  }
+
+		  total_length += padded_length + 2;
+
+		  break;
+		 default:
+		  switch (vp->type)
+		  {
+		    case PW_TYPE_STRING:
+			length = vp->lvalue;
+			*buf++ = length + 2;
+			if (vsa_length_ptr != NULL) *vsa_length_ptr += length + 2;
+			memcpy (buf, vp->strvalue, (size_t) length);
+			buf += length;
+			total_length += length + 2;
+			break;
+
+		    case PW_TYPE_IPV6ADDR:
+			length = 16;
+			*buf++ = length + 2;
+			if (vsa_length_ptr != NULL) *vsa_length_ptr += length + 2;
+			memcpy (buf, vp->strvalue, (size_t) length);
+			buf += length;
+			total_length += length + 2;
+			break;
+
+		    case PW_TYPE_IPV6PREFIX:
+			length = vp->lvalue;
+			*buf++ = length + 2;
+			if (vsa_length_ptr != NULL) *vsa_length_ptr += length + 2;
+			memcpy (buf, vp->strvalue, (size_t) length);
+			buf += length;
+			total_length += length + 2;
+			break;
+
+		    case PW_TYPE_INTEGER:
+		    case PW_TYPE_IPADDR:
+		    case PW_TYPE_DATE:
+			*buf++ = sizeof (uint32_t) + 2;
+			if (vsa_length_ptr != NULL) *vsa_length_ptr += sizeof(uint32_t) + 2;
+			lvalue = htonl (vp->lvalue);
+			memcpy (buf, (char *) &lvalue, sizeof (uint32_t));
+			buf += sizeof (uint32_t);
+			total_length += sizeof (uint32_t) + 2;
+			break;
+
+		    default:
+			break;
+		  }
+		  break;
+		}
+		vp = vp->next;
+	}
+	return total_length;
+}
+
+/** Appends a string to the provided buffer
+ *
+ * @param dest the destination buffer.
+ * @param max_size the maximum size available in the destination buffer.
+ * @param pos the current position in the dest buffer; initially must be zero.
+ * @param src the source buffer to append.
+ */
+static void strappend(char *dest, unsigned max_size, int *pos, const char *src)
+{
+	unsigned len = strlen(src) + 1;
+
+	if (*pos == -1)
+		return;
+
+	if (len + *pos > max_size) {
+		*pos = -1;
+		return;
+	}
+
+	memcpy(&dest[*pos], src, len);
+	*pos += len-1;
+	return;
+}
+
+/** Sends a request to a RADIUS server and waits for the reply
+ *
+ * @param rh a handle to parsed configuration
+ * @param data a pointer to a #SEND_DATA structure
+ * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of
+ *	any %PW_REPLY_MESSAGE received.
+ * @param flags must be %AUTH or %ACCT
+ * @return %OK_RC (0) on success, %TIMEOUT_RC on timeout %REJECT_RC on acess reject, or negative
+ *	on failure as return value.
+ */
+
+
+#define RECV_BUF_LEN    100
+static char recv_buffer[RECV_BUF_LEN];
+
+int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg, unsigned flags)
+{
+    struct sockaddr_in sa,ra;
+    int             socket;
+    fdsets          sets;
+    AUTH_HDR*       auth;
+    AUTH_HDR*       recv_auth;
+    unsigned char   vector[AUTH_VECTOR_LEN];
+    char            secret[MAX_SECRET_LENGTH + 1];
+    int             total_length;
+    int             sendLen, recvLen;
+    int             length;
+    int             pos;
+    uint8_t*        attr;
+    int             result = 0;
+    VALUE_PAIR*     vp;
+    
+    char            rcNetParams[20];
+    uint32_t        port;
+    uint8_t         tmpLen;
+    
+    initFdsets(&sets);
+    
+    memset(secret, 0, MAX_SECRET_LENGTH + 1);
+    GetRDSPasswordkStr(secret, &tmpLen);
+/*        
+	if(data->secret != NULL) {
+		//strlcpy(secret, data->secret, MAX_SECRET_LENGTH);
+		strlcpy(secret, "R04ekR4MP2", MAX_SECRET_LENGTH);
+    }
+*/
+    // Устанавливаем сетевые параметры
+    memset(rcNetParams, 0, 20);
+    GetRDSIpStr(rcNetParams, &tmpLen);
+        
+    // IP radius server
+    memset(&ra, 0, sizeof(struct sockaddr_in));
+    ra.sin_family = AF_INET;
+    ra.sin_addr.s_addr = inet_addr(rcNetParams);
+    
+    // port
+    memset(rcNetParams, 0, 20);
+    GetRDSPortStr(rcNetParams, &tmpLen);
+    port = atoi(rcNetParams);
+    ra.sin_port = htons(port);
+        
+    socket = socket(PF_INET, SOCK_DGRAM, 0);
+    if ( socket < 0 )
+    {
+        //printf("socket call failed");
+        return -1;
+    }
+        
+    // Build a request  (PW_ACCESS_REQUEST)
+    auth = (AUTH_HDR *) msg;
+	auth->code = data->code;
+	auth->id = data->seq_nbr;
+
+    rc_random_vector(vector);
+	memcpy((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
+
+	total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;
+	auth->length = htons ((unsigned short) total_length);
+	        
+    // Bind socket
+    memset(rcNetParams, 0, 20);
+    GetIpStr(rcNetParams, &tmpLen);
+    
+    memset(&sa, 0, sizeof(struct sockaddr_in));
+    sa.sin_family = AF_INET;
+    sa.sin_addr.s_addr = inet_addr(rcNetParams);
+    sa.sin_port = htons(port);
+    
+    if (bind(socket, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1)
+    {
+        //printf("Bind to Port Number %d ,IP address %s failed\n", DEVICE_PORT_NUM, DEVICE_IP_ADDR);
+        close(socket);
+        return -1;
+    }
+       
+    sendLen = sendto(socket, (char*)auth, total_length, 0, (struct sockaddr*)&ra, sizeof(ra));
+    if(sendLen < 0)
+    {
+        //printf("send failed\n");
+        close(socket);
+        return NET_ERR_RC;
+    }
+   
+    // Подготовка буфера для приема
+    memset(recv_buffer, 0, RECV_BUF_LEN);
+    
+    // Получение ответа, select
+    if (!recvSelect(&sets, &socket, 2000)) {
+        //printf("SOCK recv timeout!\r\n");
+        close(socket);
+        return NET_ERR_RC;
+    }
+    
+    // Данные можно принимать
+    socklen_t sl = sizeof(sa);
+    recvLen = recvfrom(socket, recv_buffer, RECV_BUF_LEN, 0, (struct sockaddr*)&ra, &sl);
+
+    recv_auth = (AUTH_HDR*)recv_buffer;
+    
+    // Проверки размера входящего сообщения
+    if (recvLen < AUTH_HDR_LEN || recvLen < ntohs(recv_auth->length)) {
+		//printf("radius_server: reply is too short\r\n");
+		close(socket);
+        return NET_ERR_RC;
+	}
+    
+    if (recvLen > ntohs(recv_auth->length)) 
+    {
+        recvLen = ntohs(recv_auth->length);
+    }
+    
+    // Verify that it's a valid RADIUS packet before doing ANYTHING with it.
+	attr = recv_buffer + AUTH_HDR_LEN;
+	while (attr < (recv_buffer + recvLen)) {
+		if (attr[0] == 0) {
+            //printf("radius_server: attribute zero is invalid\r\n");
+            close(socket);
+            return NET_ERR_RC;
+		}
+
+		if (attr[1] < 2) {
+            //printf("radius_server: attribute length is too small\r\n");
+            close(socket);
+            return NET_ERR_RC;
+		}
+
+		if ((attr + attr[1]) > (recv_buffer + recvLen)) {
+            //printf("radius_server: attribute overflows the packet\r\n");
+            close(socket);
+            return NET_ERR_RC;
+		}
+
+		attr += attr[1];
+	}
+    
+    
+    result = rc_check_reply(recv_auth, RECV_BUF_LEN, secret, vector, data->seq_nbr);
+    
+    length = ntohs(recv_auth->length)  - AUTH_HDR_LEN;
+	if (length > 0) {
+		data->receive_pairs = rc_avpair_gen(rh, NULL, recv_auth->data, length, 0);
+	} else {
+		data->receive_pairs = NULL;
+	}
+
+	if (result != OK_RC) {
+		return result;
+	}
+    
+    if (msg) {
+		*msg = '\0';
+		pos = 0;
+		vp = data->receive_pairs;
+		while (vp)
+		{
+			if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE, 0)))
+			{
+				strappend(msg, PW_MAX_MSG_SIZE, &pos, vp->strvalue);
+				strappend(msg, PW_MAX_MSG_SIZE, &pos, "\n");
+				vp = vp->next;
+			}
+		}
+	}
+
+	if ((recv_auth->code == PW_ACCESS_ACCEPT) ||
+		(recv_auth->code == PW_PASSWORD_ACK) ||
+		(recv_auth->code == PW_ACCOUNTING_RESPONSE))
+	{
+        result = RC_GetAccessRights(recv_buffer);
+	}
+	else if ((recv_auth->code == PW_ACCESS_REJECT) ||
+		(recv_auth->code == PW_PASSWORD_REJECT))
+	{
+		result = REJECT_RC;
+	}
+	else
+	{
+		rc_log(LOG_ERR, "rc_send_server: received RADIUS server response neither ACCEPT nor REJECT, invalid");
+		result = BADRESP_RC;
+	}
+    
+    //printf("\r\nRadius server end communication\r\n");
+    close(socket);
+    return result;
+}
+
+/** Verify items in returned packet
+ *
+ * @param auth a pointer to #AUTH_HDR.
+ * @param bufferlen the available buffer length.
+ * @param secret the secret used by the server.
+ * @param vector a random vector of %AUTH_VECTOR_LEN.
+ * @param seq_nbr a unique sequence number.
+ * @return %OK_RC upon success, %BADRESP_RC if anything looks funny.
+ */
+static int rc_check_reply (AUTH_HDR *auth, int bufferlen, char const *secret, unsigned char const *vector, uint8_t seq_nbr)
+{
+	int             secretlen;
+	int             totallen;
+	unsigned char   calc_digest[AUTH_VECTOR_LEN];
+	unsigned char   reply_digest[AUTH_VECTOR_LEN];
+#ifdef DIGEST_DEBUG
+	uint8_t		*ptr;
+#endif
+
+	totallen = ntohs (auth->length);
+	secretlen = (int)strlen (secret);
+
+	/* Do sanity checks on packet length */
+	if ((totallen < 20) || (totallen > 4096))
+	{
+		rc_log(LOG_ERR, "rc_check_reply: received RADIUS server response with invalid length");
+		return BADRESP_RC;
+	}
+
+	/* Verify buffer space, should never trigger with current buffer size and check above */
+	if ((totallen + secretlen) > bufferlen)
+	{
+		rc_log(LOG_ERR, "rc_check_reply: not enough buffer space to verify RADIUS server response");
+		return BADRESP_RC;
+	}
+
+	/* Verify that id (seq. number) matches what we sent */
+	if (auth->id != seq_nbr)
+	{
+		rc_log(LOG_ERR, "rc_check_reply: received non-matching id in RADIUS server response");
+		return BADRESP_RC;
+	}
+
+	/* Verify the reply digest */
+	memcpy ((char *) reply_digest, (char *) auth->vector, AUTH_VECTOR_LEN);
+	memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
+	memcpy ((char *) auth + totallen, secret, secretlen);
+#ifdef DIGEST_DEBUG
+        rc_log(LOG_ERR, "Calculating digest on:");
+        for (ptr = (u_char *)auth; ptr < ((u_char *)auth) + totallen + secretlen; ptr += 32) {
+                char buf[65];
+                int i;
+
+                buf[0] = '\0';
+                for (i = 0; i < 32; i++) {
+                        if (ptr + i >= ((u_char *)auth) + totallen + secretlen)
+                                break;
+                        sprintf(buf + i * 2, "%.2X", ptr[i]);
+                }
+                rc_log(LOG_ERR, "  %s", buf);
+        }
+#endif
+	rc_md5_calc (calc_digest, (unsigned char *) auth, totallen + secretlen);
+#ifdef DIGEST_DEBUG
+	rc_log(LOG_ERR, "Calculated digest is:");
+        for (ptr = (u_char *)calc_digest; ptr < ((u_char *)calc_digest) + 16; ptr += 32) {
+                char buf[65];
+                int i;
+
+                buf[0] = '\0';
+                for (i = 0; i < 32; i++) {
+                        if (ptr + i >= ((u_char *)calc_digest) + 16)
+                                break;
+                        sprintf(buf + i * 2, "%.2X", ptr[i]);
+                }
+                rc_log(LOG_ERR, "  %s", buf);
+        }
+	rc_log(LOG_ERR, "Reply digest is:");
+        for (ptr = (u_char *)reply_digest; ptr < ((u_char *)reply_digest) + 16; ptr += 32) {
+                char buf[65];
+                int i;
+
+                buf[0] = '\0';
+                for (i = 0; i < 32; i++) {
+                        if (ptr + i >= ((u_char *)reply_digest) + 16)
+                                break;
+                        sprintf(buf + i * 2, "%.2X", ptr[i]);
+                }
+                rc_log(LOG_ERR, "  %s", buf);
+        }
+#endif
+
+	if (memcmp ((char *) reply_digest, (char *) calc_digest,
+		    AUTH_VECTOR_LEN) != 0)
+	{
+		rc_log(LOG_ERR, "rc_check_reply: received invalid reply digest from RADIUS server");
+		return BADRESP_RC;
+	}
+
+	return OK_RC;
+
+}
+
+/** Generates a random vector of AUTH_VECTOR_LEN octets
+ *
+ * @param vector a buffer with at least %AUTH_VECTOR_LEN bytes.
+ */
+static void rc_random_vector (unsigned char *vector)
+{
+	int             randno;
+	int             i;
+#if defined(HAVE_GETENTROPY)
+	if (getentropy(vector, AUTH_VECTOR_LEN) >= 0) {
+		return;
+	} /* else fall through */
+#elif defined(HAVE_DEV_URANDOM)
+	int		fd;
+
+/* well, I added this to increase the security for user passwords.
+   we use /dev/urandom here, as /dev/random might block and we don't
+   need that much randomness. BTW, great idea, Ted!     -lf, 03/18/95	*/
+
+	if ((fd = open(_PATH_DEV_URANDOM, O_RDONLY)) >= 0)
+	{
+		unsigned char *pos;
+		int readcount;
+
+		i = AUTH_VECTOR_LEN;
+		pos = vector;
+		while (i > 0)
+		{
+			readcount = read(fd, (char *)pos, i);
+			if (readcount >= 0) {
+				pos += readcount;
+				i -= readcount;
+			} else {
+				if (errno != EINTR && errno != EAGAIN)
+					goto fallback;
+			}
+		}
+
+		close(fd);
+		return;
+	} /* else fall through */
+#endif
+ fallback:
+	for (i = 0; i < AUTH_VECTOR_LEN;)
+	{
+		randno = random ();
+		memcpy ((char *) vector, (char *) &randno, sizeof (int));
+		vector += sizeof (int);
+		i += sizeof (int);
+	}
+
+	return;
+}

+ 389 - 0
thirdparty/FreeRadius/lib/util.c

@@ -0,0 +1,389 @@
+/*
+ * $Id: util.c,v 1.10 2010/02/04 10:31:41 aland Exp $
+ *
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ *
+ * Copyright (C) 1995,1996,1997 Lars Fenneberg
+ *
+ * Copyright 1992 Livingston Enterprises, Inc.
+ *
+ * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
+ * and Merit Network, Inc. All Rights Reserved
+ *
+ * See the file COPYRIGHT for the respective terms and conditions.
+ * If the file is missing contact me at lf@elemental.net
+ * and I'll send you a copy.
+ *
+ */
+
+//#include <sys/time.h>
+
+#include <radius_config.h>
+#include <includes.h>
+#include <freeradius-client.h>
+#include "util.h"
+
+#define	RC_BUFSIZ	1024
+
+
+static char const * months[] =
+		{
+			"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+			"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+		};
+
+/** Turns printable string into correct tm struct entries
+ *
+ * @param valstr the printable date in 'day month year' format.
+ * @param tm the output struct.
+ */
+void rc_str2tm (char const *valstr, struct tm *tm)
+{
+	int             i;
+
+	/* Get the month */
+	for (i = 0; i < 12; i++)
+	{
+		if (strncmp (months[i], valstr, 3) == 0)
+		{
+			tm->tm_mon = i;
+			i = 13;
+		}
+	}
+
+	/* Get the Day */
+	tm->tm_mday = atoi (&valstr[4]);
+
+	/* Now the year */
+	tm->tm_year = atoi (&valstr[7]) - 1900;
+}
+
+/** Get the network interface name associated with this tty
+ *
+ * @param rh a handle to parsed configuration.
+ * @param tty the name of the tty.
+ * @return the network iface name.
+ */
+char *rc_getifname(rc_handle *rh, char const *tty)
+{
+#if defined(BSD4_4) || defined(linux)
+	int		fd;
+
+	if ((fd = open(tty, O_RDWR|O_NDELAY)) < 0) {
+		rc_log(LOG_ERR, "rc_getifname: can't open %s: %s", tty, strerror(errno));
+		return NULL;
+	}
+#endif
+
+#ifdef BSD4_4
+	strcpy(rh->ifname,ttyname(fd));
+	if (strlen(rh->ifname) < 1) {
+		rc_log(LOG_ERR, "rc_getifname: can't get attached interface of %s: %s", tty, strerror(errno));
+		close(fd);
+		return NULL;
+	}
+#elif linux
+	if (ioctl(fd, SIOCGIFNAME, rh->ifname) < 0) {
+		rc_log(LOG_ERR, "rc_getifname: can't ioctl %s: %s", tty, strerror(errno));
+		close(fd);
+		return NULL;
+	}
+#else
+	return NULL;
+#endif
+
+#if defined(BSD4_4) || defined(linux)
+	close(fd);
+	return rh->ifname;
+#endif
+}
+
+/** Reads in a string from the user (with or witout echo)
+ *
+ * @param rh a handle to parsed configuration.
+ * @param prompt the prompt to print.
+ * @param do_echo whether to echo characters.
+ * @return the data user typed or NULL.
+ */
+#ifndef _MSC_VER
+char *rc_getstr (rc_handle *rh, char const *prompt, int do_echo)
+{
+#if 0  
+	int             in, out;
+	char           *p;
+	struct termios  term_old, term_new;
+	int		is_term, flags, old_flags;
+	char		c;
+	int		flushed = 0;
+	sigset_t        newset;
+	sigset_t        oldset;
+
+	in = fileno(stdin);
+	out = fileno(stdout);
+
+	(void) sigemptyset (&newset);
+	(void) sigaddset (&newset, SIGINT);
+	(void) sigaddset (&newset, SIGTSTP);
+	(void) sigaddset (&newset, SIGQUIT);
+
+	(void) sigprocmask (SIG_BLOCK, &newset, &oldset);
+
+	if ((is_term = isatty(in)))
+	{
+
+		(void) tcgetattr (in, &term_old);
+		term_new = term_old;
+		if (do_echo)
+			term_new.c_lflag |= ECHO;
+		else
+			term_new.c_lflag &= ~ECHO;
+
+		if (tcsetattr (in, TCSAFLUSH, &term_new) == 0)
+			flushed = 1;
+
+	}
+	else
+	{
+		is_term = 0;
+		if ((flags = fcntl(in, F_GETFL, 0)) >= 0) {
+			old_flags = flags;
+			flags |= O_NONBLOCK;
+
+			fcntl(in, F_SETFL, flags);
+
+			while (read(in, &c, 1) > 0)
+				/* nothing */;
+
+			fcntl(in, F_SETFL, old_flags);
+
+			flushed = 1;
+		}
+	}
+
+	(void)write(out, prompt, strlen(prompt));
+
+	/* well, this looks ugly, but it handles the following end of line
+	   markers: \r \r\0 \r\n \n \n\r, at least at a second pass */
+
+	p = rh->buf;
+	for (;;)
+	{
+		if (read(in, &c, 1) <= 0)
+			return NULL;
+
+		if (!flushed && ((c == '\0') || (c == '\r') || (c == '\n'))) {
+			flushed = 1;
+			continue;
+		}
+
+		if ((c == '\r') || (c == '\n'))
+			break;
+
+		flushed = 1;
+
+		if (p < rh->buf + GETSTR_LENGTH)
+		{
+			if (do_echo && !is_term)
+				(void)write(out, &c, 1);
+			*p++ = c;
+		}
+	}
+
+	*p = '\0';
+
+	if (!do_echo || !is_term) (void)write(out, "\r\n", 2);
+
+	if (is_term)
+		tcsetattr (in, TCSAFLUSH, &term_old);
+	else {
+		if ((flags = fcntl(in, F_GETFL, 0)) >= 0) {
+			old_flags = flags;
+			flags |= O_NONBLOCK;
+
+			fcntl(in, F_SETFL, flags);
+
+			while (read(in, &c, 1) > 0)
+				/* nothing */;
+
+			fcntl(in, F_SETFL, old_flags);
+		}
+	}
+
+	(void) sigprocmask (SIG_SETMASK, &oldset, NULL);
+#endif
+	return rh->buf;
+}
+#endif
+
+void rc_mdelay(int msecs)
+{
+#if 0  
+	struct timeval tv;
+
+	tv.tv_sec = (int) msecs / 1000;
+	tv.tv_usec = (msecs % 1000) * 1000;
+
+	select(0, NULL, NULL, NULL, &tv);
+#endif    
+}
+
+/** Generate a quite unique string
+ *
+ * @note not that unique at all...
+ *
+ * @param rh a handle to parsed configuration.
+ * @return unique string. Memory does not need to be freed.
+ */
+
+char *rc_mksid (rc_handle *rh)
+{
+  //snprintf (rh->buf1, sizeof(rh->buf1), "%08lX%04X", (unsigned long int) time (NULL), (unsigned int) getpid ());
+  return rh->buf1;
+}
+
+/** Initialises new Radius Client handle
+ *
+ * @return a new rc_handle (free with rc_destroy).
+ */
+rc_handle *rc_new(void)
+{
+	rc_handle *rh;
+
+	rh = malloc(sizeof(*rh));
+	if (rh == NULL) {
+                rc_log(LOG_CRIT, "rc_new: out of memory");
+                return NULL;
+        }
+	memset(rh, 0, sizeof(*rh));
+	return rh;
+}
+
+/** Destroys Radius Client handle reclaiming all memory
+ *
+ * @param rh The Radius client handle to free.
+ */
+void rc_destroy(rc_handle *rh)
+{
+	rc_map2id_free(rh);
+	rc_dict_free(rh);
+	rc_config_free(rh);
+	free(rh);
+}
+
+/** Get next line from the stream.
+ *
+ * @param fp a %FILE pointer.
+ * @param len output length.
+ * @return the next line in an allocated buffer.
+ */
+char *rc_fgetln(FILE *fp, size_t *len)
+{
+	static char *buf = NULL;
+	static size_t bufsiz = 0;
+	char *ptr;
+
+	if (buf == NULL) {
+		bufsiz = RC_BUFSIZ;
+		if ((buf = malloc(bufsiz)) == NULL)
+			return NULL;
+	}
+
+	if (fgets(buf, (int)bufsiz, fp) == NULL)
+		return NULL;
+	*len = 0;
+
+	while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
+		size_t nbufsiz = bufsiz + RC_BUFSIZ;
+		char *nbuf = realloc(buf, nbufsiz);
+
+		if (nbuf == NULL) {
+			int oerrno = errno;
+			free(buf);
+			errno = oerrno;
+			buf = NULL;
+			return NULL;
+		} else
+			buf = nbuf;
+
+		*len = bufsiz;
+		if (fgets(&buf[bufsiz], RC_BUFSIZ, fp) == NULL)
+			return buf;
+
+		bufsiz = nbufsiz;
+	}
+
+	*len = (ptr - buf) + 1;
+	return buf;
+}
+
+/** Returns the current time as a double.
+ *
+ * @return current time (seconds since epoch) expressed as
+ * 	double-precision floating point number.
+ */
+double rc_getctime(void)
+{
+#if 0  
+    struct timeval timev;
+
+    if (gettimeofday(&timev, NULL) == -1)
+        return -1;
+
+    return timev.tv_sec + ((double)timev.tv_usec) / 1000000.0;
+#endif    
+    return RTC_GetUnixTime();
+}
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Copyright 2006  The FreeRADIUS server project
+ */
+
+#ifndef HAVE_STRLCPY
+
+/*
+ * Copy src to string dst of size siz.  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+rc_strlcpy(char *dst, char const *src, size_t siz)
+{
+    char *d = dst;
+    char const *s = src;
+    size_t n = siz;
+
+    /* Copy as many bytes as will fit */
+    if (n != 0 && --n != 0) {
+        do {
+            if ((*d++ = *s++) == 0)
+                break;
+        } while (--n != 0);
+    }
+
+    /* Not enough room in dst, add NUL and traverse rest of src */
+    if (n == 0) {
+        if (siz != 0)
+            *d = '\0';      /* NUL-terminate dst */
+        while (*s++)
+            ;
+    }
+
+    return(s - src - 1);    /* count does not include NUL */
+}
+
+#endif
+

+ 50 - 0
thirdparty/FreeRadius/lib/util.h

@@ -0,0 +1,50 @@
+/*
+ * util.h        Utility structures and prototypes.
+ *
+ * License:	BSD
+ *
+ */
+
+#ifndef UTIL_H
+# define UTIL_H
+
+#include <string.h>
+
+#ifndef HAVE_STRLCPY
+size_t rc_strlcpy(char *dst, char const *src, size_t siz);
+# define strlcpy rc_strlcpy
+#endif
+
+#include <includes.h>
+
+#if !defined(SA_LEN)
+#define SA_LEN(sa) \
+  (((sa)->sa_family == AF_INET) ? \
+    sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
+
+#define SS_LEN(sa) \
+  (((sa)->ss_family == AF_INET) ? \
+    sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6))
+#endif
+
+#define SA_GET_INADDR(sa) \
+  (((sa)->sa_family == AF_INET) ? \
+    ((void*)&(((struct sockaddr_in*)(sa))->sin_addr)) : ((void*)&(((struct sockaddr_in6*)(sa))->sin6_addr)))
+
+#define SA_GET_INLEN(sa) \
+  ((sa)->sa_family == AF_INET) ? \
+    sizeof(struct in_addr) : sizeof(struct in6_addr)
+
+//int rc_find_server_addr(rc_handle const *, char const *, struct addrinfo **, char *, unsigned flags);
+int rc_find_server_addr(rc_handle const *rh, char const *server_name, struct addrinfo** info, char *secret, unsigned flags);
+
+/* flags to rc_getaddrinfo() */
+#define PW_AI_PASSIVE		1
+#define PW_AI_AUTH		(1<<1)
+#define PW_AI_ACCT		(1<<2)
+
+struct addrinfo *rc_getaddrinfo (char const *host, unsigned flags);
+void rc_own_bind_addr(rc_handle *rh, struct sockaddr_storage *lia);
+
+#endif /* UTIL_H */
+

+ 103 - 0
thirdparty/FreeRadius/radius_config.h

@@ -0,0 +1,103 @@
+/******************************* (C) LiteMesh **********************************
+ * @module  template
+ * @file    template.h
+ * @version 1.0.0
+ * @date    XX.XX.XXXX
+ * $brief   template
+ *******************************************************************************
+ * @history     Version  Author         Comment
+ * XX.XX.XXXX   1.0.0    Telenkov D.A.  First release.
+ *******************************************************************************
+ */
+
+/* Define to prevent recursive  ----------------------------------------------*/
+#ifndef __RADIUS_CONFIG_H
+#define __RADIUS_CONFIG_H
+
+#include <stdint.h>
+#include <string.h>
+
+#define RC_LOG
+#define STDC_HEADERS
+#define HAVE_RAND       //  Рандом генератор
+//#define HAVE_GETENTROPY // ?
+
+// some unix defines
+#define LOG_CRIT    0
+#define LOG_ERR     0
+#define LOG_WARNING 0
+
+//typedef unsigned int size_t;
+
+// some unix structs
+
+/*
+ * Desired design of maximum size and alignment (see RFC2553)
+ */
+#define _K_SS_MAXSIZE	128	/* Implementation specific max size */
+#define _K_SS_ALIGNSIZE	(__alignof__ (struct sockaddr *))
+				/* Implementation specific desired alignment */
+
+typedef unsigned short __kernel_sa_family_t;
+
+struct __kernel_sockaddr_storage {
+	__kernel_sa_family_t	ss_family;		/* address family */
+	/* Following field(s) are implementation specific */
+	char		data[_K_SS_MAXSIZE - sizeof(unsigned short)];
+				/* space to achieve desired size, */
+				/* _SS_MAXSIZE value minus size of ss_family */
+} ;	/* force desired alignment */
+
+// -----------------------------------------------------------------------------
+
+typedef __kernel_sa_family_t	sa_family_t;
+
+// -----------------------------------------------------------------------------
+/*
+struct sockaddr {
+	char	sa_len;			// total length 
+	char	sa_family;		// address family 
+	char	sa_data[14];	// actually longer; address value 
+};
+*/
+
+#define _SS_MAXSIZE    128  /* Implementation specific max size */
+#define _SS_ALIGNSIZE  (sizeof (int64_t))
+
+#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(sa_family_t))
+#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(sa_family_t)+ \
+                      _SS_PAD1SIZE + _SS_ALIGNSIZE))
+struct sockaddr_storage {
+    sa_family_t  ss_family;  /* Address family. */
+/*
+ *  Following fields are implementation-defined.
+ */
+    char _ss_pad1[_SS_PAD1SIZE];
+        /* 6-byte pad; this is to make implementation-defined
+           pad up to alignment field that follows explicit in
+           the data structure. */
+    int64_t _ss_align;  /* Field to force desired structure
+                           storage alignment. */
+    char _ss_pad2[_SS_PAD2SIZE];
+        /* 112-byte pad to achieve desired size,
+           _SS_MAXSIZE value minus size of ss_family
+           __ss_pad1, __ss_align fields is 112. */
+};
+
+
+struct addrinfo {
+    int              ai_flags;     // AI_PASSIVE, AI_CANONNAME, etc.
+    int              ai_family;    // AF_INET, AF_INET6, AF_UNSPEC
+    int              ai_socktype;  // SOCK_STREAM, SOCK_DGRAM
+    int              ai_protocol;  // use 0 for "any"
+    size_t           ai_addrlen;   // size of ai_addr in bytes
+    struct sockaddr *ai_addr;      // struct sockaddr_in or _in6
+    char            *ai_canonname; // full canonical hostname
+
+    struct addrinfo *ai_next;      // linked list, next node
+};
+
+
+#endif /* #ifndef __RADIUS_CONFIG_H */
+
+/****************************** (C) LiteMesh ***************** end of file ****/

+ 3 - 0
user/init_task.c

@@ -35,6 +35,7 @@
 //#include "ups_params.h"
 //#include "ups_monitor.h"
 //#include <lwip/stats.h>
+#include "radius_user.h"
 
 #ifdef PRINTF_STDLIB
 #include <stdio.h>
@@ -193,6 +194,8 @@ void InitTask(void *params)
   vTaskDelay(4000);
  
   SETTINGS_ResetBootTry();
+
+ // RC_Login("test1", "12345");
   
   // Отправка трапа о перезагрузке в случае статического IP
  /* if (!dhcp)

+ 4 - 4
user/main.h

@@ -58,13 +58,13 @@
 #define __packed		__attribute__(( packed ))
 #endif
    
-//#define DEBUG
+//#define OUR_DEBUG
 
-/*#ifdef DEBUG
+#ifdef OUR_DEBUG
 #define DBG
-#else*/
+#else
 #define DBG if (0)
-//#endif
+#endif
 
    
 /* Exported macro ------------------------------------------------------------*/

+ 1 - 0
web_interface/Gruntfile.js

@@ -62,6 +62,7 @@ module.exports = function (grunt) {
         },
         files: {
           'src/wui/login.min.html':       'src/wui/login.html',
+          'src/wui/rslogin.min.html':     'src/wui/rslogin.html',
           'src/wui/index.min.html':       'src/wui/index.html',
           'src/wui/settings.min.html':    'src/wui/settings.html',
           'src/wui/info.min.html':        'src/wui/info.html',

BIN
web_interface/error.html


BIN
web_interface/index.html


BIN
web_interface/login.html


+ 35 - 0
web_interface/src/wui/rslogin.html

@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html lang="">
+<head>
+<meta charset="utf-8">
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
+<title>Мониторинг</title>
+<link href="main.css" rel="stylesheet">
+<script type="text/javascript" src="role.js"></script>
+</head>
+<body>
+  <div class="navbar navbar-default navbar-fixed-top">
+    <div class="navbar-header">
+      <div><a href="#" class="logo"></a></div>
+    </div>
+  </div>
+  <div class="wrapper" id="content">
+<!--START-->
+<h1>Radius Авторизация</h1>
+
+  <div class="panel panel-default">
+    <div class="panel-body">
+      <form action="login.cgi" method="post" class="login-form">
+        <label for="login">Логин:&nbsp;</label>
+        <input type="text" class="form-control" name="login" id="login" maxlength="16" style="margin-right: 10px;">
+        <label for="pass">Пароль:&nbsp;</label>
+        <input type="password" class="form-control" name="password" id="pass" maxlength="16">
+        <input type="submit" class="btn btn-primary" value="Войти">
+      </form>
+    </div>
+  </div>
+<!--END-->
+</div>
+</body>
+</html>

+ 2 - 2
web_interface/src/wui/settings.html

@@ -230,8 +230,8 @@
       <div class="col span_1_of_2">
         <input type="password" class="form-control" id="rs_pwd" name="rs_pwd">
       </div>
-      <label for="rs_key" class="col span_1_of_2">Код access</label>
-      <div class="col span_1_of_2">
+      <label for="rs_key" class="col span_1_of_2 hidden">Код access</label>
+      <div class="col span_1_of_2 hidden">
         <input type="password" class="form-control" id="rs_key" name="rs_key">
       </div>
     </div>

BIN
web_interface/success.html


BIN
web_interface/upload.css


BIN
web_interface/upload.js