telnet_server.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. /*
  2. * telnet_server.c
  3. *
  4. * Created on: 24.11.2017
  5. * Author: balbekova
  6. */
  7. /* Standard includes. */
  8. #include <string.h>
  9. /* lwIP core includes */
  10. #include "lwip/opt.h"
  11. #include "lwip/sockets.h"
  12. /* FreeRTOS includes. */
  13. #include "FreeRTOS.h"
  14. #include "task.h"
  15. #include "fr_timers.h"
  16. /* Utils includes. */
  17. #include "FreeRTOS_CLI.h"
  18. #include "CLI_Commands.h"
  19. #include "telnet_server.h"
  20. #include "settings_api.h"
  21. #include "parameters.h"
  22. #include "control_symbol.h"
  23. #include "log.h"
  24. #include "web_params_api.h"
  25. #define ISO_nl 0x0a
  26. #define ISO_cr 0x0d
  27. //
  28. // States
  29. //
  30. #define STATE_NORMAL 0
  31. #define STATE_IAC 1
  32. #define STATE_OPT 2
  33. #define STATE_SB 3
  34. #define STATE_OPTDAT 4
  35. #define STATE_SE 5
  36. #define STATE_CLOSE 6
  37. //
  38. // Special telnet characters
  39. //
  40. #define TELNET_SE 240 // End of subnegotiation parameters
  41. #define TELNET_NOP 241 // No operation
  42. #define TELNET_MARK 242 // Data mark
  43. #define TELNET_BRK 243 // Break
  44. #define TELNET_IP 244 // Interrupt process
  45. #define TELNET_AO 245 // Abort output
  46. #define TELNET_AYT 246 // Are you there
  47. #define TELNET_EC 247 // Erase character
  48. #define TELNET_EL 248 // Erase line
  49. #define TELNET_GA 249 // Go ahead
  50. #define TELNET_SB 250 // Start of subnegotiation parameters
  51. #define TELNET_WILL 251 // Will option code
  52. #define TELNET_WONT 252 // Won't option code
  53. #define TELNET_DO 253 // Do option code
  54. #define TELNET_DONT 254 // Don't option code
  55. #define TELNET_IAC 255 // Interpret as command
  56. //
  57. // Telnet options
  58. //
  59. #define TELOPT_TRANSMIT_BINARY 0 // Binary Transmission (RFC856)
  60. #define TELOPT_ECHO 1 // Echo (RFC857)
  61. #define TELOPT_SUPPRESS_GO_AHEAD 3 // Suppress Go Ahead (RFC858)
  62. #define TELOPT_STATUS 5 // Status (RFC859)
  63. #define TELOPT_TIMING_MARK 6 // Timing Mark (RFC860)
  64. #define TELOPT_NAOCRD 10 // Output Carriage-Return Disposition (RFC652)
  65. #define TELOPT_NAOHTS 11 // Output Horizontal Tab Stops (RFC653)
  66. #define TELOPT_NAOHTD 12 // Output Horizontal Tab Stop Disposition (RFC654)
  67. #define TELOPT_NAOFFD 13 // Output Formfeed Disposition (RFC655)
  68. #define TELOPT_NAOVTS 14 // Output Vertical Tabstops (RFC656)
  69. #define TELOPT_NAOVTD 15 // Output Vertical Tab Disposition (RFC657)
  70. #define TELOPT_NAOLFD 16 // Output Linefeed Disposition (RFC658)
  71. #define TELOPT_EXTEND_ASCII 17 // Extended ASCII (RFC698)
  72. #define TELOPT_TERMINAL_TYPE 24 // Terminal Type (RFC1091)
  73. #define TELOPT_NAWS 31 // Negotiate About Window Size (RFC1073)
  74. #define TELOPT_TERMINAL_SPEED 32 // Terminal Speed (RFC1079)
  75. #define TELOPT_TOGGLE_FLOW_CONTROL 33 // Remote Flow Control (RFC1372)
  76. #define TELOPT_LINEMODE 34 // Linemode (RFC1184)
  77. #define TELOPT_AUTHENTICATION 37 // Authentication (RFC1416)
  78. /* Repeat Login timeout, 1 seconds */
  79. #define REPEAT_SENSOR_INFO_TIME configTICK_RATE_HZ*1*1
  80. /* Set option to drop old connection if the new one is accepted */
  81. #define TCP_DROP_PREV_CONNECTION 0
  82. static portBASE_TYPE FreeRTOS_CLIAuthProcess( int8_t * pcWriteBuffer, telnetd_state_t *s );
  83. static portBASE_TYPE FreeRTOS_ChangePWDProcess( int8_t * pcWriteBuffer, telnetd_state_t *s );
  84. void SensorInfoTimerCallback(TimerHandle_t pxTimer);
  85. TimerHandle_t RepeatSensorInfoTimer;
  86. state_telnet_server_t telnetState = TELNET_AUTH;
  87. uint8_t id_change_pwd = 0;
  88. user_level_t telnet_code_auth = USER;
  89. telnetd_state_t auth_tlnt_srvr_param[NUMBER_TELNET_CONNECT];
  90. static int32_t lSocket;
  91. static int8_t *pcOutputString;
  92. static bool flagTelnetChange = false;
  93. static struct fd_set master_set, read_set, write_set;
  94. static int max_sd;
  95. static struct sockaddr_in sa;
  96. #ifdef HARDWARE_BT6708
  97. extern bool white_list_check(uint32_t check_remote_addr);
  98. #endif
  99. const int8_t * const pcWarningMessage = ( const int8_t * ) "Количество соединенений превышено. Данное соединение будет закрыто\r\n";
  100. #ifdef HARDWARE_BT6708
  101. const int8_t * const pcWelcomeMessage = ( const int8_t * ) "BT6708 command server - connection accepted.\r\nlogin:";
  102. #else
  103. const int8_t * const pcWelcomeMessage = ( const int8_t * ) "BT6706 command server - connection accepted.\r\nlogin:";
  104. #endif
  105. static const int8_t * const pcEndOfCommandOutputString = ( int8_t * ) "\r\n[Нажмите клавишу ENTER для повторного выполнения предыдущей команды]\r\n>";
  106. /**
  107. * @brief Общая структура настроек
  108. */
  109. extern SETTINGS_t sSettings;
  110. /*-----------------------------------------------------------------------------------*/
  111. /**
  112. * Close a telnet session.
  113. *
  114. * This function can be called from a telnet command in order to close
  115. * the connection.
  116. *
  117. * \param s The connection which is to be closed.
  118. *
  119. */
  120. /*-----------------------------------------------------------------------------------*/
  121. void
  122. telnetd_close(telnetd_state_t *s)
  123. {
  124. s->state = STATE_CLOSE;
  125. }
  126. static void telnetd_input(telnetd_state_t *s)
  127. {
  128. portBASE_TYPE xReturned;
  129. switch(s->telnetState){
  130. case TELNET_AUTH:
  131. case TELNET_AUTH_PASSW:
  132. if(FreeRTOS_CLIAuthProcess(pcOutputString, s)){
  133. send( s->num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
  134. memset( s->buf, 0x00, cmdMAX_INPUT_SIZE );
  135. }
  136. else{
  137. s->state = STATE_CLOSE;
  138. }
  139. break;
  140. case TELNET_CMD:
  141. /* The input string has been terminated. Was the
  142. input a quit command? */
  143. if( strcmp( "quit", ( const char * ) s->buf ) == 0 )
  144. {
  145. s->state = STATE_CLOSE;
  146. }
  147. else
  148. {
  149. /* The input string was not a quit command.
  150. Pass the string to the command interpreter. */
  151. /* See if the command is empty, indicating that the last command is
  152. to be executed again. */
  153. if( s->bufptr == 0 )
  154. {
  155. strcpy( s->buf, s->prev_cmd );
  156. }
  157. /* Transmit a line separator, just to make the
  158. output easier to read. */
  159. lwip_send( s->num_connect, "\r\n", strlen( "\r\n" ), 0 );
  160. do
  161. {
  162. /* Ensure there is not a string lingering in
  163. the output buffer. */
  164. pcOutputString[ 0 ] = 0x00;
  165. xReturned = FreeRTOS_CLIProcessCommand( s->buf, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
  166. s->telnetState = telnetState;
  167. send( s->num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
  168. } while( xReturned != pdFALSE );
  169. if( strcmp( "sensor info", ( const char * ) s->buf ) == 0 ){
  170. strcpy( s->prev_cmd, s->buf );
  171. memset( s->buf, 0x00, cmdMAX_INPUT_SIZE );
  172. xTimerStart(RepeatSensorInfoTimer, 0);
  173. }
  174. else{
  175. /* All the strings generated by the input
  176. command have been sent. Clear the input
  177. string ready to receive the next command.
  178. Remember the command that was just processed
  179. first in case it is to be processed again. */
  180. strcpy( s->prev_cmd, s->buf );
  181. memset( s->buf, 0x00, cmdMAX_INPUT_SIZE );
  182. if(s->telnetState != TELNET_CHANGE_PWD)
  183. send( s->num_connect, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
  184. }
  185. }
  186. break;
  187. case TELNET_CHANGE_PWD:
  188. case TELNET_CHANGE_PWD_ACK:
  189. FreeRTOS_ChangePWDProcess(pcOutputString, s);
  190. send( s->num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
  191. memset( s->buf, 0x00, cmdMAX_INPUT_SIZE );
  192. break;
  193. }
  194. }
  195. /*-----------------------------------------------------------------------------------*/
  196. static void getchar(telnetd_state_t *s)
  197. {
  198. if(s->buf[s->bufptr] == ISO_nl ||
  199. s->buf[s->bufptr] == 0) {
  200. s->bufptr = 0;
  201. return;
  202. }
  203. if(s->buf[s->bufptr] == ISO_cr ||
  204. s->bufptr == sizeof(s->buf) - 1) {
  205. if(s->bufptr > 0) {
  206. s->buf[s->bufptr] = 0;
  207. }
  208. telnetd_input(s);
  209. s->bufptr = 0;
  210. } else if( s->buf[s->bufptr] == '\b' || s->buf[s->bufptr] == 0x7f)
  211. {
  212. /* Backspace was pressed. Erase the last
  213. character in the string - if any. */
  214. s->buf[s->bufptr] = '\0';
  215. if( s->bufptr > 0 )
  216. {
  217. s->bufptr--;
  218. s->buf[s->bufptr] = '\0';
  219. }
  220. }
  221. else {
  222. ++s->bufptr;
  223. }
  224. }
  225. /*-----------------------------------------------------------------------------------*/
  226. static void sendopt(telnetd_state_t *s, u8_t code, u8_t option)
  227. {
  228. unsigned char buf[3];
  229. buf[0] = TELNET_IAC;
  230. buf[1] = code;
  231. buf[2] = option;
  232. send( s->num_connect, buf, 3, 0 );
  233. }
  234. void parseopt(telnetd_state_t *ts, uint8_t code, uint8_t option)
  235. {
  236. switch (option) {
  237. case TELOPT_ECHO:
  238. case TELOPT_SUPPRESS_GO_AHEAD:
  239. case TELOPT_LINEMODE:
  240. case TELOPT_NAWS:
  241. break;
  242. case TELOPT_TIMING_MARK:
  243. xTimerStop(RepeatSensorInfoTimer, 0);
  244. sendopt(ts, TELNET_WILL, TELOPT_TIMING_MARK);
  245. sendopt(ts, TELNET_MARK, 0);
  246. if(ts->telnetState != TELNET_CHANGE_PWD && ts->telnetState != TELNET_CHANGE_PWD_ACK)
  247. send( ts->num_connect, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
  248. break;
  249. default:
  250. if (code == TELNET_WILL || code == TELNET_WONT) {
  251. sendopt(ts, TELNET_DONT, option);
  252. } else {
  253. sendopt(ts, TELNET_WONT, option);
  254. }
  255. break;
  256. }
  257. }
  258. static void parseoptdat(telnetd_state_t *ts, int option, unsigned char *data, uint8_t len) {
  259. switch (option) {
  260. case TELOPT_NAWS:
  261. break;
  262. case TELOPT_TERMINAL_SPEED:
  263. break;
  264. case TELOPT_TERMINAL_TYPE:
  265. break;
  266. }
  267. }
  268. /*-----------------------------------------------------------------------------------*/
  269. static void newdata(telnetd_state_t *s)
  270. {
  271. char c;
  272. c = s->buf[s->bufptr];
  273. switch(s->state) {
  274. case STATE_IAC:
  275. switch (c) {
  276. case TELNET_IAC:
  277. s->state = STATE_NORMAL;
  278. break;
  279. case TELNET_WILL:
  280. case TELNET_WONT:
  281. case TELNET_DO:
  282. case TELNET_DONT:
  283. s->code = c;
  284. s->state = STATE_OPT;
  285. break;
  286. case TELNET_SB:
  287. s->state = STATE_SB;
  288. break;
  289. default:
  290. s->state = STATE_NORMAL;
  291. break;
  292. }
  293. break;
  294. case STATE_OPT:
  295. parseopt(s, s->code, c);
  296. s->state = STATE_NORMAL;
  297. break;
  298. case STATE_SB:
  299. s->code = c;
  300. s->optlen = 0;
  301. s->state = STATE_OPTDAT;
  302. break;
  303. case STATE_OPTDAT:
  304. if (c == TELNET_IAC) {
  305. s->state = STATE_SE;
  306. } else if (s->optlen < sizeof(s->optdata)) {
  307. s->optdata[s->optlen++] = c;
  308. }
  309. break;
  310. case STATE_SE:
  311. if (c == TELNET_SE) parseoptdat(s, s->code, s->optdata, s->optlen);
  312. s->state = STATE_NORMAL;
  313. break;
  314. case STATE_NORMAL:
  315. if(c == TELNET_IAC) {
  316. s->state = STATE_IAC;
  317. } else {
  318. getchar(s);
  319. }
  320. break;
  321. }
  322. }
  323. /*-----------------------------------------------------------*/
  324. /* Stop server */
  325. static void stop_server(void) {
  326. /* Clean up all of the sockets that are open */
  327. for (int i = 0; i <= max_sd; ++i)
  328. {
  329. if (FD_ISSET(i, &master_set)) {
  330. DBG printf("Close sock %d\n", i);
  331. closesocket(i);
  332. FD_CLR(i, &master_set);
  333. }
  334. }
  335. DBG printf("Portgw stopped\n");
  336. }
  337. /* Start server */
  338. static bool start_server(uint16_t port)
  339. {
  340. int res;
  341. lSocket = socket(PF_INET, SOCK_STREAM, 0);
  342. if (lSocket < 0) {
  343. DBG printf("Socket create failed\r\n");
  344. return false;
  345. }
  346. res = fcntl(lSocket, F_SETFL, O_NONBLOCK);
  347. if (res < 0) {
  348. DBG printf("fcntl() failed");
  349. closesocket(lSocket);
  350. return false;
  351. }
  352. memset(&sa, 0, sizeof(struct sockaddr_in));
  353. sa.sin_family = AF_INET;
  354. sa.sin_addr.s_addr = IPADDR_ANY;
  355. sa.sin_port = htons(port);
  356. if (bind(lSocket, (struct sockaddr *)&sa, sizeof(sa)) == -1)
  357. {
  358. DBG printf("Bind to port %d failed\n", port);
  359. closesocket(lSocket);
  360. return false;
  361. }
  362. res = listen(lSocket, 20);
  363. if (res < 0) {
  364. DBG printf("Listen failed failed\r\n");
  365. closesocket(lSocket);
  366. return false;
  367. }
  368. FD_ZERO(&master_set);
  369. max_sd = lSocket;
  370. FD_SET(lSocket, &master_set);
  371. DBG printf("Port %d opened\n", port);
  372. return true;
  373. }
  374. void vBasicSocketsCommandInterpreterTask( void *pvParameters )
  375. {
  376. int32_t lBytes, lAddrLen = sizeof( struct sockaddr_in );
  377. struct sockaddr_in sLocalAddr;
  378. struct sockaddr_in client_addr;
  379. int new_sd;
  380. int desc_ready, rc;
  381. struct timeval timeout;
  382. uint16_t port;
  383. bool enabled;
  384. bool firstrun = true;
  385. #ifdef HARDWARE_BT6708
  386. struct sockaddr_in sa_temp;
  387. socklen_t len;
  388. #endif
  389. static int active_sd = -1;
  390. static uint8_t cnt_conn = 0;
  391. uint8_t cur_cnt = 0;
  392. FD_ZERO(&master_set);
  393. timeout.tv_sec = 5;
  394. timeout.tv_usec = 0;
  395. ( void ) pvParameters;
  396. pcOutputString = FreeRTOS_CLIGetOutputBuffer();
  397. enabled = sSettings.sTelnet.TelnetEnable;
  398. port = ( uint16_t ) sSettings.sTelnet.port;
  399. while (1) {
  400. /* Check if network settings was changed */
  401. if ((sSettings.sTelnet.port != port) ||
  402. (sSettings.sTelnet.TelnetEnable != enabled) ||
  403. (firstrun))
  404. {
  405. if (!firstrun || sSettings.sTelnet.port != port) {
  406. /* Stop server */
  407. stop_server();
  408. }
  409. if (sSettings.sTelnet.TelnetEnable) {
  410. /* (Re)start server */
  411. if (!start_server(sSettings.sTelnet.port)) {
  412. DBG printf("Server start error\n");
  413. firstrun = true;
  414. vTaskDelay(5000);
  415. continue;
  416. }
  417. }
  418. else {
  419. /* Obtain the address of the output buffer. Note there is no mutual
  420. exclusion on this buffer as it is assumed only one command console
  421. interface will be used at any one time. */
  422. firstrun = true;
  423. vTaskDelay(5000);
  424. continue;
  425. }
  426. firstrun = false;
  427. port = sSettings.sTelnet.port;
  428. enabled = sSettings.sTelnet.TelnetEnable;
  429. }
  430. if (!enabled) {
  431. firstrun = true;
  432. vTaskDelay(5000);
  433. continue;
  434. }
  435. memcpy(&read_set, &master_set, sizeof(master_set));
  436. DBG printf("Waiting on select()...\n");
  437. rc = select(max_sd + 1, &read_set, NULL, NULL, &timeout);
  438. DBG printf(" select() returned %d\n", rc);
  439. if (rc < 0) {
  440. DBG printf(" select() failed\n");
  441. }
  442. if (rc == 0) {
  443. DBG printf(" select() timed out.\n");
  444. }
  445. /* One or more descriptors are readable. Need to \
  446. * determine which ones they are. */
  447. desc_ready = rc;
  448. for (int i=0; i <= max_sd && desc_ready > 0; ++i) {
  449. /*******************************************************/
  450. /* Check to see if this descriptor is ready */
  451. /*******************************************************/
  452. if (FD_ISSET(i, &read_set)) {
  453. /* A descriptor was found that was readable - one \
  454. * less has to be looked for. This is being done \
  455. * so that we can stop looking at the working set \
  456. * once we have found all of the descriptors that \
  457. * were ready. */
  458. desc_ready -= 1;
  459. /* Check to see if this is the listening socket */
  460. if (i == lSocket) {
  461. DBG printf(" Listening socket is readable\n");
  462. /* Accept all incoming connections that are */
  463. /* queued up on the listening socket before we */
  464. /* loop back and call select again. */
  465. do {
  466. /* Accept each incoming connection. If */
  467. /* accept fails with EWOULDBLOCK, then we */
  468. /* have accepted all of them. Any other */
  469. /* failure on accept will cause us to end the */
  470. /* server. */
  471. new_sd = accept(lSocket, NULL, NULL);
  472. if (new_sd < 0) {
  473. if (errno != EWOULDBLOCK) {
  474. DBG printf(" accept() failed\n");
  475. }
  476. break;
  477. }
  478. /* Add the new incoming connection to the */
  479. /* master read set */
  480. printf(" New incoming connection - %d\n", new_sd);
  481. FD_SET(new_sd, &master_set);
  482. if (new_sd > max_sd) {
  483. max_sd = new_sd;
  484. }
  485. #ifdef HARDWARE_BT6708
  486. lwip_getpeername(new_sd, &sa_temp, &len);
  487. #endif
  488. // recv( new_sd, &auth_tlnt_srvr_param[cur_cnt].buf, 27, 0 );
  489. // Send initial options
  490. if(cnt_conn < NUMBER_TELNET_CONNECT){
  491. for(uint8_t k = 0; k < NUMBER_TELNET_CONNECT; k ++){
  492. if(auth_tlnt_srvr_param[k].active_conn == false){
  493. auth_tlnt_srvr_param[k].active_conn = true;
  494. auth_tlnt_srvr_param[k].num_connect = new_sd;
  495. auth_tlnt_srvr_param[k].telnetState = TELNET_AUTH;
  496. auth_tlnt_srvr_param[k].state = STATE_NORMAL;
  497. #ifdef HARDWARE_BT6708
  498. auth_tlnt_srvr_param[k].flagWhiteListTelnet = white_list_check(sa_temp.sin_addr.s_addr);
  499. #elif HARDWARE_BT6706
  500. auth_tlnt_srvr_param[k].flagWhiteListTelnet = true;
  501. #endif
  502. while(recv( new_sd, &auth_tlnt_srvr_param[k].buf[auth_tlnt_srvr_param[k].bufptr], 1, MSG_DONTWAIT ) > 0){
  503. newdata(&auth_tlnt_srvr_param[k]);
  504. vTaskDelay(5);
  505. }
  506. sendopt(&auth_tlnt_srvr_param[k], TELNET_WILL, TELOPT_SUPPRESS_GO_AHEAD);
  507. sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_ECHO);
  508. sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_LINEMODE);
  509. vTaskDelay(50);
  510. while(recv( new_sd, &auth_tlnt_srvr_param[k].buf[auth_tlnt_srvr_param[k].bufptr], 1, MSG_DONTWAIT ) > 0){
  511. newdata(&auth_tlnt_srvr_param[k]);
  512. vTaskDelay(5);
  513. }
  514. send( new_sd, pcWelcomeMessage, strlen( ( const char * ) pcWelcomeMessage ), 0 );
  515. break;
  516. }
  517. }
  518. cnt_conn ++;
  519. }
  520. else{
  521. send( new_sd, pcWarningMessage, strlen( ( const char * ) pcWarningMessage ), 0 );
  522. closesocket(new_sd);
  523. FD_CLR(new_sd, &master_set);
  524. while (FD_ISSET(max_sd, &master_set) == false) {
  525. max_sd -= 1;
  526. }
  527. }
  528. #if TCP_DROP_PREV_CONNECTION
  529. /* Close previous active connection */
  530. if (active_sd != -1 && active_sd != new_sd) {
  531. DBG printf(" Close prev active connection %d\n", active_sd);
  532. close(active_sd);
  533. FD_CLR(active_sd, &master_set);
  534. if (active_sd == max_sd) {
  535. while (FD_ISSET(max_sd, &master_set) == false) {
  536. max_sd -= 1;
  537. }
  538. }
  539. }
  540. /* Mark new connection as active */
  541. active_sd = new_sd;
  542. DBG printf(" New active connection %d\n", active_sd);
  543. #endif
  544. /* Loop back up and accept another incoming */
  545. /* connection */
  546. } while (new_sd != -1);
  547. }
  548. /* This is not the listening socket, therefore an */
  549. /* existing connection must be readable */
  550. else {
  551. DBG printf(" Descriptor %d is readable\n", i);
  552. for(cur_cnt = 0; cur_cnt < NUMBER_TELNET_CONNECT; cur_cnt ++){
  553. if(auth_tlnt_srvr_param[cur_cnt].num_connect == i){
  554. telnetState = auth_tlnt_srvr_param[cur_cnt].telnetState;
  555. telnet_code_auth = auth_tlnt_srvr_param[cur_cnt].telnet_code_auth;
  556. switch (telnet_code_auth) {
  557. case ADMIN:
  558. snprintf(name_login_telnet, sizeof(name_login_telnet), "Администратор");
  559. break;
  560. case USER:
  561. snprintf(name_login_telnet, sizeof(name_login_telnet), "Пользователь");
  562. break;
  563. default:
  564. break;
  565. }
  566. break;
  567. }
  568. }
  569. /* Receive data on this connection until the */
  570. /* recv fails with EWOULDBLOCK. If any other */
  571. /* failure occurs, we will close the */
  572. /* connection. */
  573. if ((lBytes = recv(i, &auth_tlnt_srvr_param[cur_cnt].buf[auth_tlnt_srvr_param[cur_cnt].bufptr], 1, 0 )) > 0) {
  574. newdata(&auth_tlnt_srvr_param[cur_cnt]);
  575. }
  576. if (lBytes < 0) {
  577. if (errno != EWOULDBLOCK){
  578. DBG printf(" recv() failed\n");
  579. auth_tlnt_srvr_param[cur_cnt].state = STATE_CLOSE;
  580. }
  581. }
  582. /* Check to see if the connection has been */
  583. /* closed by the client */
  584. if (lBytes == 0) {
  585. DBG printf(" Connection closed\n");
  586. auth_tlnt_srvr_param[cur_cnt].state = STATE_CLOSE;
  587. }
  588. /* If the close_conn flag was turned on, we need */
  589. /* to clean up this active connection. This */
  590. /* clean up process includes removing the */
  591. /* descriptor from the master set and */
  592. /* determining the new maximum descriptor value */
  593. /* based on the bits that are still turned on in */
  594. /* the master set. */
  595. if (auth_tlnt_srvr_param[cur_cnt].state == STATE_CLOSE) {
  596. auth_tlnt_srvr_param[cur_cnt].state = STATE_NORMAL;
  597. auth_tlnt_srvr_param[cur_cnt].num_connect = 0;
  598. auth_tlnt_srvr_param[cur_cnt].active_conn = false;
  599. auth_tlnt_srvr_param[cur_cnt].telnetState = TELNET_AUTH;
  600. auth_tlnt_srvr_param[cur_cnt].telnet_code_auth = USER;
  601. cnt_conn -= 1;
  602. closesocket(i);
  603. FD_CLR(i, &master_set);
  604. if (i == max_sd) {
  605. while (FD_ISSET(max_sd, &master_set) == false) {
  606. max_sd -= 1;
  607. }
  608. }
  609. }
  610. }
  611. }
  612. }
  613. }
  614. }
  615. void telnet_server_init(void) {
  616. for(uint8_t i = 0; i < NUMBER_TELNET_CONNECT; i++){
  617. auth_tlnt_srvr_param[i].num_connect = 0;
  618. auth_tlnt_srvr_param[i].active_conn = false;
  619. auth_tlnt_srvr_param[i].telnetState = TELNET_AUTH;
  620. auth_tlnt_srvr_param[i].telnet_code_auth = USER;
  621. }
  622. vRegisterCLICommands();
  623. xTaskCreate(vBasicSocketsCommandInterpreterTask, ( char * ) "vBasicSocketsCommandInterpreterTask", 8*configMINIMAL_STACK_SIZE , NULL, tskIDLE_PRIORITY + 1, NULL);
  624. RepeatSensorInfoTimer = xTimerCreate("SensorInfoTmr", REPEAT_SENSOR_INFO_TIME, pdFALSE, ( void * ) 0, SensorInfoTimerCallback);
  625. }
  626. void SensorInfoTimerCallback(TimerHandle_t pxTimer) {
  627. portBASE_TYPE xReturned = pdTRUE;
  628. do
  629. {
  630. /* Ensure there is not a string lingering in
  631. the output buffer. */
  632. pcOutputString[ 0 ] = 0x00;
  633. xReturned = FreeRTOS_CLIProcessCommand( "sensor info", pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
  634. for(uint8_t i = 0; i < NUMBER_TELNET_CONNECT; i++){
  635. if(auth_tlnt_srvr_param[i].active_conn){
  636. lwip_send( auth_tlnt_srvr_param[i].num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
  637. }
  638. }
  639. } while( xReturned != pdFALSE );
  640. xTimerStart(RepeatSensorInfoTimer, 0);
  641. }
  642. static portBASE_TYPE FreeRTOS_CLIAuthProcess( int8_t * pcWriteBuffer, telnetd_state_t *s )
  643. {
  644. portBASE_TYPE xReturn = pdTRUE;
  645. uint32_t len;
  646. uint8_t valueLen, user_id;
  647. char WebPassword[MAX_WEB_PASSWD_LEN];
  648. char WebLogin[MAX_WEB_LOGIN_LEN];
  649. char password[cmdMAX_INPUT_SIZE] = { 0 };
  650. const int8_t * const pcPSWHeader = ( int8_t * ) "\r\npassword:";
  651. const int8_t * const pcLoginHeader = ( int8_t * ) "\r\nlogin:";
  652. memset(pcWriteBuffer, 0, configCOMMAND_INT_MAX_OUTPUT_SIZE);
  653. switch(s->telnetState){
  654. case TELNET_AUTH:
  655. memset(s->login, 0, MAX_WEB_LOGIN_LEN);
  656. len = strlen(s->buf);
  657. if(len < MAX_WEB_LOGIN_LEN){
  658. strncpy(s->login, s->buf, len);
  659. sendopt(s, TELNET_WILL, TELOPT_ECHO);
  660. strncpy( ( char * ) pcWriteBuffer, ( const char * ) pcPSWHeader, strlen( ( char * ) pcPSWHeader ) );
  661. s->telnetState = TELNET_AUTH_PASSW;
  662. xReturn = pdTRUE;
  663. }
  664. else{
  665. xReturn = pdFALSE;
  666. }
  667. break;
  668. case TELNET_AUTH_PASSW:
  669. sendopt(s, TELNET_WONT, TELOPT_ECHO);
  670. memset(name_login_telnet, 0, 50);
  671. memset(password, 0, MAX_WEB_PASSWD_LEN);
  672. len = strlen(s->buf);
  673. strncpy(password, s->buf, len);
  674. #ifdef HARDWARE_BT6708
  675. if(!s->flagWhiteListTelnet){
  676. xReturn = pdFALSE;
  677. }
  678. else
  679. #endif
  680. {
  681. for (user_id = 0; user_id < MAX_WEB_USERS; user_id++) {
  682. GetUserLogin(user_id, WebLogin, &valueLen);
  683. GetUserPassword(user_id, WebPassword, &valueLen);
  684. /* Check login and password */
  685. if ((strncmp(WebLogin, s->login, MAX_WEB_LOGIN_LEN) == 0) &&
  686. (strncmp(WebPassword, password, MAX_WEB_PASSWD_LEN) == 0)) {
  687. /* Login and pass are valid */
  688. s->telnet_code_auth = user_id;
  689. s->login_err = 0;
  690. strcpy( ( char * ) pcWriteBuffer, "\r\nАвторизация успешно пройдена\r\n>" );
  691. s->telnetState = TELNET_CMD;
  692. switch (user_id) {
  693. case 0:
  694. snprintf(name_login_telnet, sizeof(name_login_telnet), "Администратор");
  695. break;
  696. case 1:
  697. snprintf(name_login_telnet, sizeof(name_login_telnet), "Пользователь");
  698. break;
  699. default:
  700. break;
  701. }
  702. log_event_data(LOG_LOGIN_TELNET, name_login_telnet);
  703. xReturn = pdTRUE;
  704. break;
  705. }
  706. else{
  707. xReturn = pdFALSE;
  708. }
  709. }
  710. }
  711. break;
  712. default:
  713. xReturn = pdFALSE;
  714. s->telnetState = TELNET_AUTH;
  715. return xReturn;
  716. break;
  717. }
  718. if(xReturn == pdFALSE){
  719. s->telnetState = TELNET_AUTH;
  720. if(s->login_err < 4){
  721. s->login_err ++;
  722. #ifdef HARDWARE_BT6708
  723. if(!s->flagWhiteListTelnet)
  724. strcpy( ( char * ) pcWriteBuffer, "\r\nДоступ запрешен! Ваш IP-адрес находится вне диапазона доверительных хостов\r\n" );
  725. else
  726. #endif
  727. strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка авторизации\r\n" );
  728. strncat( ( char * ) pcWriteBuffer, ( const char * ) pcLoginHeader, strlen( ( char * ) pcLoginHeader ) );
  729. xReturn = pdTRUE;
  730. }
  731. else{
  732. s->login_err = 0;
  733. xReturn = pdFALSE;
  734. }
  735. }
  736. return xReturn;
  737. }
  738. static portBASE_TYPE FreeRTOS_ChangePWDProcess( int8_t * pcWriteBuffer, telnetd_state_t *s )
  739. {
  740. portBASE_TYPE xReturn = pdTRUE;
  741. uint32_t len;
  742. static char password[ MAX_WEB_PASSWD_LEN ] = { 0 };
  743. char password2[ MAX_WEB_PASSWD_LEN ] = { 0 };
  744. const int8_t * const pcNewPSWHeader = ( int8_t * ) "\r\nВведите повторно новый пароль:";
  745. memset(pcWriteBuffer, 0, configCOMMAND_INT_MAX_OUTPUT_SIZE);
  746. len = strlen(s->buf);
  747. if(s->telnetState == TELNET_CHANGE_PWD){
  748. memset(password, 0, MAX_WEB_PASSWD_LEN);
  749. if(len >= MAX_WEB_PASSWD_LEN){
  750. strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
  751. s->telnetState = TELNET_CMD;
  752. }
  753. else{
  754. if(!control_string_en_digit(s->buf, len)){
  755. strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
  756. s->telnetState = TELNET_CMD;
  757. }
  758. else{
  759. strncpy(password, s->buf, len);
  760. strncpy( ( char * ) pcWriteBuffer, ( const char * ) pcNewPSWHeader, strlen( ( char * ) pcNewPSWHeader ) );
  761. s->telnetState = TELNET_CHANGE_PWD_ACK;
  762. }
  763. }
  764. }
  765. else{
  766. s->telnetState = TELNET_CHANGE_PWD;
  767. memset(password2, 0, cmdMAX_INPUT_SIZE);
  768. if(len >= MAX_WEB_LOGIN_LEN){
  769. strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
  770. s->telnetState = TELNET_CMD;
  771. }
  772. else{
  773. strncpy(password2, s->buf, len);
  774. if (strncmp(password, password2, MAX_WEB_PASSWD_LEN) == 0) {
  775. memcpy(sSettings.sAuth[id_change_pwd].password, password, 11);
  776. telnet_act = true;
  777. HTTP_SaveSettings();
  778. log_event_data(LOG_PSW_CHANGE, name_login_telnet);
  779. strcpy( ( char * ) pcWriteBuffer, "\r\nПароль успешно изменен\r\n>" );
  780. s->telnetState = TELNET_CMD;
  781. xReturn = pdTRUE;
  782. }
  783. else{
  784. strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
  785. s->telnetState = TELNET_CMD;
  786. }
  787. }
  788. }
  789. return xReturn;
  790. }