123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- /*
- * telnet_server.c
- *
- * Created on: 24.11.2017
- * Author: balbekova
- */
- /* Standard includes. */
- #include <string.h>
- /* lwIP core includes */
- #include "lwip/opt.h"
- #include "lwip/sockets.h"
- /* FreeRTOS includes. */
- #include "FreeRTOS.h"
- #include "task.h"
- #include "fr_timers.h"
- /* Utils includes. */
- #include "FreeRTOS_CLI.h"
- #include "CLI_Commands.h"
- #include "telnet_server.h"
- #include "settings_api.h"
- #include "parameters.h"
- #include "control_symbol.h"
- #include "log.h"
- #include "web_params_api.h"
- /* Dimensions the buffer into which input characters are placed. */
- #define cmdMAX_INPUT_SIZE 144
- /* Repeat Login timeout, 1 seconds */
- #define REPEAT_SENSOR_INFO_TIME configTICK_RATE_HZ*1*1
- static portBASE_TYPE FreeRTOS_CLIAuthProcess( const int8_t * const pcCommandInput, int8_t * pcWriteBuffer );
- static portBASE_TYPE FreeRTOS_ChangePWDProcess( const int8_t * const pcCommandInput, int8_t * pcWriteBuffer );
- void SensorInfoTimerCallback(TimerHandle_t pxTimer);
- TimerHandle_t RepeatSensorInfoTimer;
- state_telnet_server_t telnetState = TELNET_AUTH;
- uint8_t id_change_pwd = 0;
- user_level_t telnet_code_auth = USER;
- static int32_t lClientFd;
- static int8_t *pcOutputString;
- /**
- * @brief Общая структура настроек
- */
- extern SETTINGS_t sSettings;
- /*-----------------------------------------------------------*/
- void vBasicSocketsCommandInterpreterTask( void *pvParameters )
- {
- int32_t lSocket, lBytes, lAddrLen = sizeof( struct sockaddr_in );
- struct sockaddr_in sLocalAddr;
- struct sockaddr_in client_addr;
- const int8_t * const pcWelcomeMessage = ( const int8_t * ) "BT6706 command server - connection accepted.\r\nlogin:";
- static const int8_t * const pcEndOfCommandOutputString = ( int8_t * ) "\r\n[Press ENTER to execute the previous command again]\r\n>";
- int8_t cInChar, cInputIndex;
- static int8_t cInputString[ cmdMAX_INPUT_SIZE ] = { 0 }, cLastInputString[ cmdMAX_INPUT_SIZE ] = { 0 };
- portBASE_TYPE xReturned;
- ( void ) pvParameters;
- lSocket = lwip_socket( AF_INET, SOCK_STREAM, 0 );
- if( lSocket >= 0 )
- {
- /* Obtain the address of the output buffer. Note there is no mutual
- exclusion on this buffer as it is assumed only one command console
- interface will be used at any one time. */
- pcOutputString = FreeRTOS_CLIGetOutputBuffer();
- memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));
- sLocalAddr.sin_family = AF_INET;
- sLocalAddr.sin_len = sizeof(sLocalAddr);
- sLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- sLocalAddr.sin_port = ntohs( ( ( uint16_t ) 23 ) );
- if( lwip_bind( lSocket, ( struct sockaddr *) &sLocalAddr, sizeof( sLocalAddr ) ) < 0 )
- {
- lwip_close( lSocket );
- vTaskDelete( NULL );
- }
- if( lwip_listen( lSocket, 20 ) != 0 )
- {
- lwip_close( lSocket );
- vTaskDelete( NULL );
- }
- /* Ensure the input string starts clear. */
- cInputString[ 0 ] = 0;
- cLastInputString[ 0 ] = 0;
- for( ;; )
- {
- lClientFd = lwip_accept( lSocket, ( struct sockaddr * ) &client_addr, ( u32_t * ) &lAddrLen );
- if( lClientFd > 0L )
- {
- lBytes = lwip_recv( lClientFd, cInputString, 27, 0 );
- telnetState = TELNET_AUTH;
- lwip_send( lClientFd, pcWelcomeMessage, strlen( ( const char * ) pcWelcomeMessage ), 0 );
- cInputIndex = 0;
- memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
- do
- {
- lBytes = lwip_recv( lClientFd, &cInChar, sizeof( cInChar ), 0 );
- if( lBytes > 0L )
- {
- if( cInChar == '\n' )
- {
- switch(telnetState){
- case TELNET_AUTH:
- if(FreeRTOS_CLIAuthProcess(cInputString, pcOutputString)){
- lwip_send( lClientFd, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
- cInputIndex = 0;
- memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
- }
- else{
- /* Set lBytes to 0 to close the connection. */
- lBytes = 0L;
- }
- break;
- case TELNET_CMD:
- /* The input string has been terminated. Was the
- input a quit command? */
- if( strcmp( "quit", ( const char * ) cInputString ) == 0 )
- {
- /* Set lBytes to 0 to close the connection. */
- lBytes = 0L;
- }
- else
- {
- /* The input string was not a quit command.
- Pass the string to the command interpreter. */
- /* See if the command is empty, indicating that the last command is
- to be executed again. */
- if( cInputIndex == 0 )
- {
- strcpy( ( char * ) cInputString, ( char * ) cLastInputString );
- }
- /* Transmit a line separator, just to make the
- output easier to read. */
- lwip_send( lClientFd, "\r\n", strlen( "\r\n" ), 0 );
- do
- {
- /* Ensure there is not a string lingering in
- the output buffer. */
- pcOutputString[ 0 ] = 0x00;
- xReturned = FreeRTOS_CLIProcessCommand( cInputString, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
- lwip_send( lClientFd, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
- } while( xReturned != pdFALSE );
- if( strcmp( "sensor info", ( const char * ) cInputString ) == 0 ){
- strcpy( ( char * ) cLastInputString, ( char * ) cInputString );
- cInputIndex = 0;
- memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
- xTimerStart(RepeatSensorInfoTimer, 0);
- }
- else{
- /* All the strings generated by the input
- command have been sent. Clear the input
- string ready to receive the next command.
- Remember the command that was just processed
- first in case it is to be processed again. */
- strcpy( ( char * ) cLastInputString, ( char * ) cInputString );
- cInputIndex = 0;
- memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
- if(telnetState != TELNET_CHANGE_PWD)
- lwip_send( lClientFd, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
- }
- }
- break;
- case TELNET_CHANGE_PWD:
- FreeRTOS_ChangePWDProcess(cInputString, pcOutputString);
- lwip_send( lClientFd, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
- cInputIndex = 0;
- memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
- break;
- }
- }
- else
- {
- if( cInChar == '\r' )
- {
- /* Ignore the character. */
- }
- else if( cInChar == '\b' )
- {
- /* Backspace was pressed. Erase the last
- character in the string - if any. */
- if( cInputIndex > 0 )
- {
- cInputIndex--;
- cInputString[ cInputIndex ] = '\0';
- }
- }
- else
- {
- /* A character was entered. Add it to the string
- entered so far. When a \n is entered the complete
- string will be passed to the command interpreter. */
- if( cInputIndex < cmdMAX_INPUT_SIZE )
- {
- cInputString[ cInputIndex ] = cInChar;
- cInputIndex++;
- }
- if( strcmp( "\377\364\377\375\006", ( const char * ) cInputString ) == 0 ){
- xTimerStop(RepeatSensorInfoTimer, 0);
- cInputIndex = 0;
- memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
- cInputString[0] = 255;
- cInputString[1] = 251;
- cInputString[2] = 6;
- cInputString[3] = 255;
- cInputString[4] = 242;
- //if(telnetState != TELNET_CHANGE_PWD)
- //lwip_send( lClientFd, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
- lwip_send( lClientFd, cInputString, strlen( ( const char * ) cInputString ), 0 );
- memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
- if(telnetState != TELNET_CHANGE_PWD)
- lwip_send( lClientFd, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
- }
- }
- }
- }
- } while( lBytes > 0L );
- lwip_close( lClientFd );
- }
- }
- }
- /* Will only get here if a listening socket could not be created. */
- vTaskDelete( NULL );
- }
- void telnet_server_init(void) {
- vRegisterCLICommands();
- xTaskCreate(vBasicSocketsCommandInterpreterTask, ( char * ) "vBasicSocketsCommandInterpreterTask", 8*configMINIMAL_STACK_SIZE , NULL, tskIDLE_PRIORITY, NULL);
- RepeatSensorInfoTimer = xTimerCreate("SensorInfoTmr", REPEAT_SENSOR_INFO_TIME, pdFALSE, ( void * ) 0, SensorInfoTimerCallback);
- }
- void SensorInfoTimerCallback(TimerHandle_t pxTimer) {
- portBASE_TYPE xReturned = pdTRUE;
- do
- {
- /* Ensure there is not a string lingering in
- the output buffer. */
- pcOutputString[ 0 ] = 0x00;
- xReturned = FreeRTOS_CLIProcessCommand( "sensor info", pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
- lwip_send( lClientFd, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
- } while( xReturned != pdFALSE );
- xTimerStart(RepeatSensorInfoTimer, 0);
- }
- static portBASE_TYPE FreeRTOS_CLIAuthProcess( const int8_t * const pcCommandInput, int8_t * pcWriteBuffer )
- {
- portBASE_TYPE xReturn = pdTRUE;
- uint32_t len;
- uint8_t valueLen, user_id;
- char WebPassword[MAX_WEB_PASSWD_LEN];
- char WebLogin[MAX_WEB_LOGIN_LEN];
- static uint8_t login_err = 0;
- static uint8_t telnet_state_auth = 0;
- static char login[ cmdMAX_INPUT_SIZE ] = { 0 };
- char password[ cmdMAX_INPUT_SIZE ] = { 0 };
- const int8_t * const pcPSWHeader = ( int8_t * ) "\r\npassword:";
- const int8_t * const pcLoginHeader = ( int8_t * ) "\r\nlogin:";
- memset(pcWriteBuffer, 0, configCOMMAND_INT_MAX_OUTPUT_SIZE);
- if(telnet_state_auth == 0){
- telnet_state_auth = 1;
- memset(login, 0, cmdMAX_INPUT_SIZE);
- len = strlen((char *)pcCommandInput);
- strncpy(login, (char *)pcCommandInput, len);
- strncpy( ( char * ) pcWriteBuffer, ( const char * ) pcPSWHeader, strlen( ( char * ) pcPSWHeader ) );
- xReturn = pdTRUE;
- }
- else{
- memset(name_login_telnet, 0, 50);
- telnet_state_auth = 0;
- memset(password, 0, cmdMAX_INPUT_SIZE);
- len = strlen((char *)pcCommandInput);
- strncpy(password, (char *)pcCommandInput, len);
- 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 */
- telnet_code_auth = user_id;
- login_err = 0;
- strcpy( ( char * ) pcWriteBuffer, "\r\nАвторизация успешно пройдена\r\n>" );
- telnetState = TELNET_CMD;
- xReturn = pdTRUE;
- break;
- }
- else{
- xReturn = pdFALSE;
- }
- }
- if(xReturn == pdFALSE){
- if(login_err < 4){
- login_err ++;
- strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка авторизации\r\n" );
- strncat( ( char * ) pcWriteBuffer, ( const char * ) pcLoginHeader, strlen( ( char * ) pcLoginHeader ) );
- xReturn = pdTRUE;
- }
- else{
- login_err = 0;
- xReturn = pdFALSE;
- }
- }
- switch (user_id) {
- case 0:
- snprintf(name_login_telnet, sizeof(name_login_telnet), "Администратор");
- break;
- case 1:
- snprintf(name_login_telnet, sizeof(name_login_telnet), "Пользователь");
- break;
- default:
- break;
- }
- log_event_data(LOG_LOGIN_TELNET, name_login_telnet);
- }
- return xReturn;
- }
- static portBASE_TYPE FreeRTOS_ChangePWDProcess( const int8_t * const pcCommandInput, int8_t * pcWriteBuffer )
- {
- portBASE_TYPE xReturn = pdTRUE;
- uint32_t len;
- static uint8_t telnet_state_change_pwd = 0;
- static char password[ MAX_WEB_LOGIN_LEN ] = { 0 };
- char password2[ MAX_WEB_LOGIN_LEN ] = { 0 };
- const int8_t * const pcNewPSWHeader = ( int8_t * ) "\r\nВведите повторно новый пароль:";
- memset(pcWriteBuffer, 0, configCOMMAND_INT_MAX_OUTPUT_SIZE);
- if(telnet_state_change_pwd == 0){
- telnet_state_change_pwd = 1;
- memset(password, 0, MAX_WEB_LOGIN_LEN);
- len = strlen((char *)pcCommandInput);
- if(len >= MAX_WEB_LOGIN_LEN){
- strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
- telnetState = TELNET_CMD;
- }
- else{
- if(!control_string_en_digit((char *)pcCommandInput, len)){
- strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
- telnetState = TELNET_CMD;
- }
- else{
- strncpy(password, (char *)pcCommandInput, len);
- strncpy( ( char * ) pcWriteBuffer, ( const char * ) pcNewPSWHeader, strlen( ( char * ) pcNewPSWHeader ) );
- }
- }
- }
- else{
- telnet_state_change_pwd = 0;
- memset(password2, 0, cmdMAX_INPUT_SIZE);
- len = strlen((char *)pcCommandInput);
- if(len >= MAX_WEB_LOGIN_LEN){
- strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
- telnetState = TELNET_CMD;
- }
- else{
- strncpy(password2, (char *)pcCommandInput, len);
- if (strncmp(password, password2, MAX_WEB_PASSWD_LEN) == 0) {
- memcpy(sSettings.sAuth[id_change_pwd].password, password, 11);
- telnet_act = true;
- HTTP_SaveSettings();
- log_event_data(LOG_PSW_CHANGE, name_login_telnet);
- strcpy( ( char * ) pcWriteBuffer, "\r\nПароль успешно изменен\r\n>" );
- telnetState = TELNET_CMD;
- xReturn = pdTRUE;
- }
- else{
- strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
- telnetState = TELNET_CMD;
- }
- }
- }
- return xReturn;
- }
|