|
@@ -28,17 +28,74 @@
|
|
|
#include "web_params_api.h"
|
|
|
|
|
|
|
|
|
+#define ISO_nl 0x0a
|
|
|
+#define ISO_cr 0x0d
|
|
|
+
|
|
|
+//
|
|
|
+// States
|
|
|
+//
|
|
|
+
|
|
|
+#define STATE_NORMAL 0
|
|
|
+#define STATE_IAC 1
|
|
|
+#define STATE_OPT 2
|
|
|
+#define STATE_SB 3
|
|
|
+#define STATE_OPTDAT 4
|
|
|
+#define STATE_SE 5
|
|
|
+#define STATE_CLOSE 6
|
|
|
+
|
|
|
+//
|
|
|
+// Special telnet characters
|
|
|
+//
|
|
|
+
|
|
|
+#define TELNET_SE 240 // End of subnegotiation parameters
|
|
|
+#define TELNET_NOP 241 // No operation
|
|
|
+#define TELNET_MARK 242 // Data mark
|
|
|
+#define TELNET_BRK 243 // Break
|
|
|
+#define TELNET_IP 244 // Interrupt process
|
|
|
+#define TELNET_AO 245 // Abort output
|
|
|
+#define TELNET_AYT 246 // Are you there
|
|
|
+#define TELNET_EC 247 // Erase character
|
|
|
+#define TELNET_EL 248 // Erase line
|
|
|
+#define TELNET_GA 249 // Go ahead
|
|
|
+#define TELNET_SB 250 // Start of subnegotiation parameters
|
|
|
+#define TELNET_WILL 251 // Will option code
|
|
|
+#define TELNET_WONT 252 // Won't option code
|
|
|
+#define TELNET_DO 253 // Do option code
|
|
|
+#define TELNET_DONT 254 // Don't option code
|
|
|
+#define TELNET_IAC 255 // Interpret as command
|
|
|
+
|
|
|
+//
|
|
|
+// Telnet options
|
|
|
+//
|
|
|
+#define TELOPT_TRANSMIT_BINARY 0 // Binary Transmission (RFC856)
|
|
|
+#define TELOPT_ECHO 1 // Echo (RFC857)
|
|
|
+#define TELOPT_SUPPRESS_GO_AHEAD 3 // Suppress Go Ahead (RFC858)
|
|
|
+#define TELOPT_STATUS 5 // Status (RFC859)
|
|
|
+#define TELOPT_TIMING_MARK 6 // Timing Mark (RFC860)
|
|
|
+#define TELOPT_NAOCRD 10 // Output Carriage-Return Disposition (RFC652)
|
|
|
+#define TELOPT_NAOHTS 11 // Output Horizontal Tab Stops (RFC653)
|
|
|
+#define TELOPT_NAOHTD 12 // Output Horizontal Tab Stop Disposition (RFC654)
|
|
|
+#define TELOPT_NAOFFD 13 // Output Formfeed Disposition (RFC655)
|
|
|
+#define TELOPT_NAOVTS 14 // Output Vertical Tabstops (RFC656)
|
|
|
+#define TELOPT_NAOVTD 15 // Output Vertical Tab Disposition (RFC657)
|
|
|
+#define TELOPT_NAOLFD 16 // Output Linefeed Disposition (RFC658)
|
|
|
+#define TELOPT_EXTEND_ASCII 17 // Extended ASCII (RFC698)
|
|
|
+#define TELOPT_TERMINAL_TYPE 24 // Terminal Type (RFC1091)
|
|
|
+#define TELOPT_NAWS 31 // Negotiate About Window Size (RFC1073)
|
|
|
+#define TELOPT_TERMINAL_SPEED 32 // Terminal Speed (RFC1079)
|
|
|
+#define TELOPT_TOGGLE_FLOW_CONTROL 33 // Remote Flow Control (RFC1372)
|
|
|
+#define TELOPT_LINEMODE 34 // Linemode (RFC1184)
|
|
|
+#define TELOPT_AUTHENTICATION 37 // Authentication (RFC1416)
|
|
|
+
|
|
|
|
|
|
-/* 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
|
|
|
|
|
|
/* Set option to drop old connection if the new one is accepted */
|
|
|
#define TCP_DROP_PREV_CONNECTION 0
|
|
|
|
|
|
-static portBASE_TYPE FreeRTOS_CLIAuthProcess( const int8_t * const pcCommandInput, int8_t * pcWriteBuffer, uint8_t num_conn );
|
|
|
-static portBASE_TYPE FreeRTOS_ChangePWDProcess( const int8_t * const pcCommandInput, int8_t * pcWriteBuffer, uint8_t num_conn );
|
|
|
+static portBASE_TYPE FreeRTOS_CLIAuthProcess( int8_t * pcWriteBuffer, telnetd_state_t *s );
|
|
|
+static portBASE_TYPE FreeRTOS_ChangePWDProcess( int8_t * pcWriteBuffer, telnetd_state_t *s );
|
|
|
void SensorInfoTimerCallback(TimerHandle_t pxTimer);
|
|
|
|
|
|
TimerHandle_t RepeatSensorInfoTimer;
|
|
@@ -47,9 +104,8 @@ state_telnet_server_t telnetState = TELNET_AUTH;
|
|
|
uint8_t id_change_pwd = 0;
|
|
|
user_level_t telnet_code_auth = USER;
|
|
|
|
|
|
-auth_telnet_server_t auth_tlnt_srvr_param[NUMBER_TELNET_CONNECT];
|
|
|
+telnetd_state_t auth_tlnt_srvr_param[NUMBER_TELNET_CONNECT];
|
|
|
|
|
|
-static int32_t lClientFd;
|
|
|
static int32_t lSocket;
|
|
|
static int8_t *pcOutputString;
|
|
|
static bool flagTelnetChange = false;
|
|
@@ -61,11 +117,262 @@ static struct sockaddr_in sa;
|
|
|
extern bool white_list_check(uint32_t check_remote_addr);
|
|
|
#endif
|
|
|
|
|
|
+const int8_t * const pcWarningMessage = ( const int8_t * ) "Количество соединенений превышено. Данное соединение будет закрыто\r\n";
|
|
|
+#ifdef HARDWARE_BT6708
|
|
|
+const int8_t * const pcWelcomeMessage = ( const int8_t * ) "BT6708 command server - connection accepted.\r\nlogin:";
|
|
|
+#else
|
|
|
+const int8_t * const pcWelcomeMessage = ( const int8_t * ) "BT6706 command server - connection accepted.\r\nlogin:";
|
|
|
+#endif
|
|
|
+static const int8_t * const pcEndOfCommandOutputString = ( int8_t * ) "\r\n[Нажмите клавишу ENTER для повторного выполнения предыдущей команды]\r\n>";
|
|
|
+
|
|
|
/**
|
|
|
* @brief Общая структура настроек
|
|
|
*/
|
|
|
extern SETTINGS_t sSettings;
|
|
|
|
|
|
+/*-----------------------------------------------------------------------------------*/
|
|
|
+/**
|
|
|
+ * Close a telnet session.
|
|
|
+ *
|
|
|
+ * This function can be called from a telnet command in order to close
|
|
|
+ * the connection.
|
|
|
+ *
|
|
|
+ * \param s The connection which is to be closed.
|
|
|
+ *
|
|
|
+ */
|
|
|
+/*-----------------------------------------------------------------------------------*/
|
|
|
+void
|
|
|
+telnetd_close(telnetd_state_t *s)
|
|
|
+{
|
|
|
+ s->state = STATE_CLOSE;
|
|
|
+}
|
|
|
+
|
|
|
+static void telnetd_input(telnetd_state_t *s)
|
|
|
+{
|
|
|
+ portBASE_TYPE xReturned;
|
|
|
+
|
|
|
+ switch(s->telnetState){
|
|
|
+ case TELNET_AUTH:
|
|
|
+ case TELNET_AUTH_PASSW:
|
|
|
+ if(FreeRTOS_CLIAuthProcess(pcOutputString, s)){
|
|
|
+ send( s->num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
|
|
|
+ memset( s->buf, 0x00, cmdMAX_INPUT_SIZE );
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ s->state = STATE_CLOSE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case TELNET_CMD:
|
|
|
+ /* The input string has been terminated. Was the
|
|
|
+ input a quit command? */
|
|
|
+ if( strcmp( "quit", ( const char * ) s->buf ) == 0 )
|
|
|
+ {
|
|
|
+ s->state = STATE_CLOSE;
|
|
|
+ }
|
|
|
+ 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( s->bufptr == 0 )
|
|
|
+ {
|
|
|
+ strcpy( s->buf, s->prev_cmd );
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Transmit a line separator, just to make the
|
|
|
+ output easier to read. */
|
|
|
+ lwip_send( s->num_connect, "\r\n", strlen( "\r\n" ), 0 );
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+ /* Ensure there is not a string lingering in
|
|
|
+ the output buffer. */
|
|
|
+ pcOutputString[ 0 ] = 0x00;
|
|
|
+ xReturned = FreeRTOS_CLIProcessCommand( s->buf, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
|
|
|
+ s->telnetState = telnetState;
|
|
|
+ send( s->num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
|
|
|
+
|
|
|
+ } while( xReturned != pdFALSE );
|
|
|
+
|
|
|
+ if( strcmp( "sensor info", ( const char * ) s->buf ) == 0 ){
|
|
|
+ strcpy( s->prev_cmd, s->buf );
|
|
|
+ memset( s->buf, 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( s->prev_cmd, s->buf );
|
|
|
+ memset( s->buf, 0x00, cmdMAX_INPUT_SIZE );
|
|
|
+ if(s->telnetState != TELNET_CHANGE_PWD)
|
|
|
+ send( s->num_connect, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case TELNET_CHANGE_PWD:
|
|
|
+ case TELNET_CHANGE_PWD_ACK:
|
|
|
+ FreeRTOS_ChangePWDProcess(pcOutputString, s);
|
|
|
+ send( s->num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
|
|
|
+ memset( s->buf, 0x00, cmdMAX_INPUT_SIZE );
|
|
|
+ break;
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*-----------------------------------------------------------------------------------*/
|
|
|
+static void getchar(telnetd_state_t *s)
|
|
|
+{
|
|
|
+ if(s->buf[s->bufptr] == ISO_nl ||
|
|
|
+ s->buf[s->bufptr] == 0) {
|
|
|
+ s->bufptr = 0;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(s->buf[s->bufptr] == ISO_cr ||
|
|
|
+ s->bufptr == sizeof(s->buf) - 1) {
|
|
|
+ if(s->bufptr > 0) {
|
|
|
+ s->buf[s->bufptr] = 0;
|
|
|
+ }
|
|
|
+ telnetd_input(s);
|
|
|
+ s->bufptr = 0;
|
|
|
+ } else if( s->buf[s->bufptr] == '\b' || s->buf[s->bufptr] == 0x7f)
|
|
|
+ {
|
|
|
+ /* Backspace was pressed. Erase the last
|
|
|
+ character in the string - if any. */
|
|
|
+ s->buf[s->bufptr] = '\0';
|
|
|
+ if( s->bufptr > 0 )
|
|
|
+ {
|
|
|
+ s->bufptr--;
|
|
|
+ s->buf[s->bufptr] = '\0';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ ++s->bufptr;
|
|
|
+ }
|
|
|
+}
|
|
|
+/*-----------------------------------------------------------------------------------*/
|
|
|
+static void sendopt(telnetd_state_t *s, u8_t code, u8_t option)
|
|
|
+{
|
|
|
+ unsigned char buf[3];
|
|
|
+ buf[0] = TELNET_IAC;
|
|
|
+ buf[1] = code;
|
|
|
+ buf[2] = option;
|
|
|
+ send( s->num_connect, buf, 3, 0 );
|
|
|
+}
|
|
|
+
|
|
|
+void parseopt(telnetd_state_t *ts, uint8_t code, uint8_t option)
|
|
|
+{
|
|
|
+
|
|
|
+ switch (option) {
|
|
|
+ case TELOPT_ECHO:
|
|
|
+ case TELOPT_SUPPRESS_GO_AHEAD:
|
|
|
+ case TELOPT_LINEMODE:
|
|
|
+ case TELOPT_NAWS:
|
|
|
+ break;
|
|
|
+
|
|
|
+ case TELOPT_TIMING_MARK:
|
|
|
+
|
|
|
+ xTimerStop(RepeatSensorInfoTimer, 0);
|
|
|
+ sendopt(ts, TELNET_WILL, TELOPT_TIMING_MARK);
|
|
|
+ sendopt(ts, TELNET_MARK, 0);
|
|
|
+ if(ts->telnetState != TELNET_CHANGE_PWD && ts->telnetState != TELNET_CHANGE_PWD_ACK)
|
|
|
+ send( ts->num_connect, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ if (code == TELNET_WILL || code == TELNET_WONT) {
|
|
|
+ sendopt(ts, TELNET_DONT, option);
|
|
|
+ } else {
|
|
|
+ sendopt(ts, TELNET_WONT, option);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void parseoptdat(telnetd_state_t *ts, int option, unsigned char *data, uint8_t len) {
|
|
|
+
|
|
|
+ switch (option) {
|
|
|
+ case TELOPT_NAWS:
|
|
|
+ break;
|
|
|
+
|
|
|
+ case TELOPT_TERMINAL_SPEED:
|
|
|
+ break;
|
|
|
+
|
|
|
+ case TELOPT_TERMINAL_TYPE:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*-----------------------------------------------------------------------------------*/
|
|
|
+static void newdata(telnetd_state_t *s)
|
|
|
+{
|
|
|
+ char c;
|
|
|
+
|
|
|
+ c = s->buf[s->bufptr];
|
|
|
+ switch(s->state) {
|
|
|
+ case STATE_IAC:
|
|
|
+ switch (c) {
|
|
|
+ case TELNET_IAC:
|
|
|
+ s->state = STATE_NORMAL;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case TELNET_WILL:
|
|
|
+ case TELNET_WONT:
|
|
|
+ case TELNET_DO:
|
|
|
+ case TELNET_DONT:
|
|
|
+ s->code = c;
|
|
|
+ s->state = STATE_OPT;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case TELNET_SB:
|
|
|
+ s->state = STATE_SB;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ s->state = STATE_NORMAL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case STATE_OPT:
|
|
|
+ parseopt(s, s->code, c);
|
|
|
+ s->state = STATE_NORMAL;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case STATE_SB:
|
|
|
+ s->code = c;
|
|
|
+ s->optlen = 0;
|
|
|
+ s->state = STATE_OPTDAT;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case STATE_OPTDAT:
|
|
|
+ if (c == TELNET_IAC) {
|
|
|
+ s->state = STATE_SE;
|
|
|
+ } else if (s->optlen < sizeof(s->optdata)) {
|
|
|
+ s->optdata[s->optlen++] = c;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case STATE_SE:
|
|
|
+ if (c == TELNET_SE) parseoptdat(s, s->code, s->optdata, s->optlen);
|
|
|
+ s->state = STATE_NORMAL;
|
|
|
+ break;
|
|
|
+ case STATE_NORMAL:
|
|
|
+ if(c == TELNET_IAC) {
|
|
|
+ s->state = STATE_IAC;
|
|
|
+ } else {
|
|
|
+ getchar(s);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
/* Stop server */
|
|
@@ -135,20 +442,9 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
|
|
|
int32_t lBytes, lAddrLen = sizeof( struct sockaddr_in );
|
|
|
struct sockaddr_in sLocalAddr;
|
|
|
struct sockaddr_in client_addr;
|
|
|
- const int8_t * const pcWarningMessage = ( const int8_t * ) "Количество соединенений превышено. Данное соединение будет закрыто\r\n";
|
|
|
-#ifdef HARDWARE_BT6708
|
|
|
- const int8_t * const pcWelcomeMessage = ( const int8_t * ) "BT6708 command server - connection accepted.\r\nlogin:";
|
|
|
-#else
|
|
|
- const int8_t * const pcWelcomeMessage = ( const int8_t * ) "BT6706 command server - connection accepted.\r\nlogin:";
|
|
|
-#endif
|
|
|
- static const int8_t * const pcEndOfCommandOutputString = ( int8_t * ) "\r\n[Нажмите клавишу ENTER для повторного выполнения предыдущей команды]\r\n>";
|
|
|
- int8_t cInChar, cInputIndex;
|
|
|
- static int8_t cInputString[ cmdMAX_INPUT_SIZE ] = { 0 }, cLastInputString[ cmdMAX_INPUT_SIZE ] = { 0 };
|
|
|
- portBASE_TYPE xReturned;
|
|
|
int new_sd;
|
|
|
int desc_ready, rc;
|
|
|
struct timeval timeout;
|
|
|
- bool close_conn;
|
|
|
uint16_t port;
|
|
|
bool enabled;
|
|
|
bool firstrun = true;
|
|
@@ -276,19 +572,32 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
|
|
|
#ifdef HARDWARE_BT6708
|
|
|
lwip_getpeername(new_sd, &sa_temp, &len);
|
|
|
#endif
|
|
|
- //recv( new_sd, cInputString, 27, 0 );
|
|
|
- recv( new_sd, cInputString, 1, 0 );
|
|
|
+ // recv( new_sd, &auth_tlnt_srvr_param[cur_cnt].buf, 27, 0 );
|
|
|
+ // Send initial options
|
|
|
if(cnt_conn < NUMBER_TELNET_CONNECT){
|
|
|
for(uint8_t k = 0; k < NUMBER_TELNET_CONNECT; k ++){
|
|
|
if(auth_tlnt_srvr_param[k].active_conn == false){
|
|
|
auth_tlnt_srvr_param[k].active_conn = true;
|
|
|
auth_tlnt_srvr_param[k].num_connect = new_sd;
|
|
|
auth_tlnt_srvr_param[k].telnetState = TELNET_AUTH;
|
|
|
+ auth_tlnt_srvr_param[k].state = STATE_NORMAL;
|
|
|
#ifdef HARDWARE_BT6708
|
|
|
auth_tlnt_srvr_param[k].flagWhiteListTelnet = white_list_check(sa_temp.sin_addr.s_addr);
|
|
|
#elif HARDWARE_BT6706
|
|
|
auth_tlnt_srvr_param[k].flagWhiteListTelnet = true;
|
|
|
#endif
|
|
|
+ while(recv( new_sd, &auth_tlnt_srvr_param[k].buf[auth_tlnt_srvr_param[k].bufptr], 1, MSG_DONTWAIT ) > 0){
|
|
|
+ newdata(&auth_tlnt_srvr_param[k]);
|
|
|
+ vTaskDelay(5);
|
|
|
+ }
|
|
|
+ sendopt(&auth_tlnt_srvr_param[k], TELNET_WILL, TELOPT_SUPPRESS_GO_AHEAD);
|
|
|
+ sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_ECHO);
|
|
|
+ sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_LINEMODE);
|
|
|
+ vTaskDelay(50);
|
|
|
+ while(recv( new_sd, &auth_tlnt_srvr_param[k].buf[auth_tlnt_srvr_param[k].bufptr], 1, MSG_DONTWAIT ) > 0){
|
|
|
+ newdata(&auth_tlnt_srvr_param[k]);
|
|
|
+ vTaskDelay(5);
|
|
|
+ }
|
|
|
send( new_sd, pcWelcomeMessage, strlen( ( const char * ) pcWelcomeMessage ), 0 );
|
|
|
break;
|
|
|
}
|
|
@@ -304,8 +613,6 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- cInputIndex = 0;
|
|
|
- memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
|
|
|
#if TCP_DROP_PREV_CONNECTION
|
|
|
/* Close previous active connection */
|
|
|
if (active_sd != -1 && active_sd != new_sd) {
|
|
@@ -332,7 +639,6 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
|
|
|
/* existing connection must be readable */
|
|
|
else {
|
|
|
DBG printf(" Descriptor %d is readable\n", i);
|
|
|
- close_conn = false;
|
|
|
|
|
|
for(cur_cnt = 0; cur_cnt < NUMBER_TELNET_CONNECT; cur_cnt ++){
|
|
|
if(auth_tlnt_srvr_param[cur_cnt].num_connect == i){
|
|
@@ -356,147 +662,15 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
|
|
|
/* recv fails with EWOULDBLOCK. If any other */
|
|
|
/* failure occurs, we will close the */
|
|
|
/* connection. */
|
|
|
- if ((lBytes = recv(i, &cInChar, sizeof( cInChar ), 0 )) > 0) {
|
|
|
-
|
|
|
- if( lBytes > 0L )
|
|
|
- {
|
|
|
- if( cInChar == '\n' )
|
|
|
- {
|
|
|
- switch(auth_tlnt_srvr_param[cur_cnt].telnetState){
|
|
|
- case TELNET_AUTH:
|
|
|
- if(FreeRTOS_CLIAuthProcess(cInputString, pcOutputString, cur_cnt)){
|
|
|
- send( i, 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( i, "\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 );
|
|
|
- auth_tlnt_srvr_param[cur_cnt].telnetState = telnetState;
|
|
|
- send( i, 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 );
|
|
|
- lClientFd = i;
|
|
|
- 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(auth_tlnt_srvr_param[cur_cnt].telnetState != TELNET_CHANGE_PWD)
|
|
|
- send( i, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- case TELNET_CHANGE_PWD:
|
|
|
- FreeRTOS_ChangePWDProcess(cInputString, pcOutputString, cur_cnt);
|
|
|
- send( i, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
|
|
|
- cInputIndex = 0;
|
|
|
- memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
|
|
|
- break;
|
|
|
+ if ((lBytes = recv(i, &auth_tlnt_srvr_param[cur_cnt].buf[auth_tlnt_srvr_param[cur_cnt].bufptr], 1, 0 )) > 0) {
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- 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 if( cInChar == '\t' ){
|
|
|
- /*FreeRTOS_CLICompleteCMDCommand(cInputString, pcOutputString);
|
|
|
- strcpy((char *)cInputString, (char *)pcOutputString);
|
|
|
- send( i, pcOutputString, strlen( ( const char * ) pcOutputString ), 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[i] != TELNET_CHANGE_PWD)
|
|
|
- //lwip_send( lClientFd, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
|
|
|
- send( i, cInputString, strlen( ( const char * ) cInputString ), 0 );
|
|
|
- memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
|
|
|
- if(auth_tlnt_srvr_param[cur_cnt].telnetState != TELNET_CHANGE_PWD)
|
|
|
- send( i, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ newdata(&auth_tlnt_srvr_param[cur_cnt]);
|
|
|
}
|
|
|
|
|
|
if (lBytes < 0) {
|
|
|
if (errno != EWOULDBLOCK){
|
|
|
DBG printf(" recv() failed\n");
|
|
|
- close_conn = true;
|
|
|
+ auth_tlnt_srvr_param[cur_cnt].state = STATE_CLOSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -504,7 +678,7 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
|
|
|
/* closed by the client */
|
|
|
if (lBytes == 0) {
|
|
|
DBG printf(" Connection closed\n");
|
|
|
- close_conn = true;
|
|
|
+ auth_tlnt_srvr_param[cur_cnt].state = STATE_CLOSE;
|
|
|
}
|
|
|
|
|
|
/* If the close_conn flag was turned on, we need */
|
|
@@ -514,7 +688,8 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
|
|
|
/* determining the new maximum descriptor value */
|
|
|
/* based on the bits that are still turned on in */
|
|
|
/* the master set. */
|
|
|
- if (close_conn) {
|
|
|
+ if (auth_tlnt_srvr_param[cur_cnt].state == STATE_CLOSE) {
|
|
|
+ auth_tlnt_srvr_param[cur_cnt].state = STATE_NORMAL;
|
|
|
auth_tlnt_srvr_param[cur_cnt].num_connect = 0;
|
|
|
auth_tlnt_srvr_param[cur_cnt].active_conn = false;
|
|
|
auth_tlnt_srvr_param[cur_cnt].telnetState = TELNET_AUTH;
|
|
@@ -532,7 +707,6 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
void telnet_server_init(void) {
|
|
@@ -556,44 +730,52 @@ void SensorInfoTimerCallback(TimerHandle_t pxTimer) {
|
|
|
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 );
|
|
|
+ for(uint8_t i = 0; i < NUMBER_TELNET_CONNECT; i++){
|
|
|
+ if(auth_tlnt_srvr_param[i].active_conn){
|
|
|
+ lwip_send( auth_tlnt_srvr_param[i].num_connect, 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, uint8_t num_conn )
|
|
|
+static portBASE_TYPE FreeRTOS_CLIAuthProcess( int8_t * pcWriteBuffer, telnetd_state_t *s )
|
|
|
{
|
|
|
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[NUMBER_TELNET_CONNECT] = {0};
|
|
|
- static uint8_t telnet_state_auth[NUMBER_TELNET_CONNECT] = {0};
|
|
|
- static char login[NUMBER_TELNET_CONNECT][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[num_conn] == 0){
|
|
|
- telnet_state_auth[num_conn] = 1;
|
|
|
- memset(&login[num_conn][0], 0, cmdMAX_INPUT_SIZE);
|
|
|
- len = strlen((char *)pcCommandInput);
|
|
|
- strncpy(&login[num_conn][0], (char *)pcCommandInput, len);
|
|
|
- strncpy( ( char * ) pcWriteBuffer, ( const char * ) pcPSWHeader, strlen( ( char * ) pcPSWHeader ) );
|
|
|
- xReturn = pdTRUE;
|
|
|
- }
|
|
|
- else{
|
|
|
+ switch(s->telnetState){
|
|
|
+ case TELNET_AUTH:
|
|
|
+ memset(s->login, 0, MAX_WEB_LOGIN_LEN);
|
|
|
+ len = strlen(s->buf);
|
|
|
+ if(len < MAX_WEB_LOGIN_LEN){
|
|
|
+ strncpy(s->login, s->buf, len);
|
|
|
+ sendopt(s, TELNET_WILL, TELOPT_ECHO);
|
|
|
+ strncpy( ( char * ) pcWriteBuffer, ( const char * ) pcPSWHeader, strlen( ( char * ) pcPSWHeader ) );
|
|
|
+ s->telnetState = TELNET_AUTH_PASSW;
|
|
|
+ xReturn = pdTRUE;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ xReturn = pdFALSE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case TELNET_AUTH_PASSW:
|
|
|
+ sendopt(s, TELNET_WONT, TELOPT_ECHO);
|
|
|
memset(name_login_telnet, 0, 50);
|
|
|
- telnet_state_auth[num_conn] = 0;
|
|
|
- memset(password, 0, cmdMAX_INPUT_SIZE);
|
|
|
- len = strlen((char *)pcCommandInput);
|
|
|
- strncpy(password, (char *)pcCommandInput, len);
|
|
|
+ memset(password, 0, MAX_WEB_PASSWD_LEN);
|
|
|
+ len = strlen(s->buf);
|
|
|
+ strncpy(password, s->buf, len);
|
|
|
#ifdef HARDWARE_BT6708
|
|
|
- if(!auth_tlnt_srvr_param[num_conn].flagWhiteListTelnet){
|
|
|
+ if(!s->flagWhiteListTelnet){
|
|
|
xReturn = pdFALSE;
|
|
|
}
|
|
|
else
|
|
@@ -605,14 +787,14 @@ static portBASE_TYPE FreeRTOS_CLIAuthProcess( const int8_t * const pcCommandInpu
|
|
|
GetUserPassword(user_id, WebPassword, &valueLen);
|
|
|
|
|
|
/* Check login and password */
|
|
|
- if ((strncmp(WebLogin, &login[num_conn][0], MAX_WEB_LOGIN_LEN) == 0) &&
|
|
|
+ if ((strncmp(WebLogin, s->login, MAX_WEB_LOGIN_LEN) == 0) &&
|
|
|
(strncmp(WebPassword, password, MAX_WEB_PASSWD_LEN) == 0)) {
|
|
|
|
|
|
/* Login and pass are valid */
|
|
|
- auth_tlnt_srvr_param[num_conn].telnet_code_auth = user_id;
|
|
|
- login_err[num_conn] = 0;
|
|
|
+ s->telnet_code_auth = user_id;
|
|
|
+ s->login_err = 0;
|
|
|
strcpy( ( char * ) pcWriteBuffer, "\r\nАвторизация успешно пройдена\r\n>" );
|
|
|
- auth_tlnt_srvr_param[num_conn].telnetState = TELNET_CMD;
|
|
|
+ s->telnetState = TELNET_CMD;
|
|
|
switch (user_id) {
|
|
|
case 0:
|
|
|
snprintf(name_login_telnet, sizeof(name_login_telnet), "Администратор");
|
|
@@ -633,69 +815,74 @@ static portBASE_TYPE FreeRTOS_CLIAuthProcess( const int8_t * const pcCommandInpu
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if(xReturn == pdFALSE){
|
|
|
- if(login_err[num_conn] < 4){
|
|
|
- login_err[num_conn] ++;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ xReturn = pdFALSE;
|
|
|
+ s->telnetState = TELNET_AUTH;
|
|
|
+ return xReturn;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(xReturn == pdFALSE){
|
|
|
+ s->telnetState = TELNET_AUTH;
|
|
|
+ if(s->login_err < 4){
|
|
|
+ s->login_err ++;
|
|
|
#ifdef HARDWARE_BT6708
|
|
|
- if(!auth_tlnt_srvr_param[num_conn].flagWhiteListTelnet)
|
|
|
- strcpy( ( char * ) pcWriteBuffer, "\r\nДоступ запрешен! Ваш IP-адрес находится вне диапазона доверительных хостов\r\n" );
|
|
|
- else
|
|
|
+ if(!s->flagWhiteListTelnet)
|
|
|
+ strcpy( ( char * ) pcWriteBuffer, "\r\nДоступ запрешен! Ваш IP-адрес находится вне диапазона доверительных хостов\r\n" );
|
|
|
+ else
|
|
|
#endif
|
|
|
- strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка авторизации\r\n" );
|
|
|
- strncat( ( char * ) pcWriteBuffer, ( const char * ) pcLoginHeader, strlen( ( char * ) pcLoginHeader ) );
|
|
|
- xReturn = pdTRUE;
|
|
|
- }
|
|
|
- else{
|
|
|
- login_err[num_conn] = 0;
|
|
|
- xReturn = pdFALSE;
|
|
|
- }
|
|
|
+ strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка авторизации\r\n" );
|
|
|
+ strncat( ( char * ) pcWriteBuffer, ( const char * ) pcLoginHeader, strlen( ( char * ) pcLoginHeader ) );
|
|
|
+ xReturn = pdTRUE;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ s->login_err = 0;
|
|
|
+ xReturn = pdFALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
return xReturn;
|
|
|
}
|
|
|
|
|
|
-static portBASE_TYPE FreeRTOS_ChangePWDProcess( const int8_t * const pcCommandInput, int8_t * pcWriteBuffer, uint8_t num_conn )
|
|
|
+static portBASE_TYPE FreeRTOS_ChangePWDProcess( int8_t * pcWriteBuffer, telnetd_state_t *s )
|
|
|
{
|
|
|
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 };
|
|
|
+ static char password[ MAX_WEB_PASSWD_LEN ] = { 0 };
|
|
|
+ char password2[ MAX_WEB_PASSWD_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){
|
|
|
+ len = strlen(s->buf);
|
|
|
+ if(s->telnetState == TELNET_CHANGE_PWD){
|
|
|
+ memset(password, 0, MAX_WEB_PASSWD_LEN);
|
|
|
+ if(len >= MAX_WEB_PASSWD_LEN){
|
|
|
strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
|
|
|
- auth_tlnt_srvr_param[num_conn].telnetState = TELNET_CMD;
|
|
|
+ s->telnetState = TELNET_CMD;
|
|
|
}
|
|
|
else{
|
|
|
- if(!control_string_en_digit((char *)pcCommandInput, len)){
|
|
|
+ if(!control_string_en_digit(s->buf, len)){
|
|
|
strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
|
|
|
- auth_tlnt_srvr_param[num_conn].telnetState = TELNET_CMD;
|
|
|
+ s->telnetState = TELNET_CMD;
|
|
|
}
|
|
|
else{
|
|
|
- strncpy(password, (char *)pcCommandInput, len);
|
|
|
+ strncpy(password, s->buf, len);
|
|
|
strncpy( ( char * ) pcWriteBuffer, ( const char * ) pcNewPSWHeader, strlen( ( char * ) pcNewPSWHeader ) );
|
|
|
+ s->telnetState = TELNET_CHANGE_PWD_ACK;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else{
|
|
|
- telnet_state_change_pwd = 0;
|
|
|
+ s->telnetState = TELNET_CHANGE_PWD;
|
|
|
memset(password2, 0, cmdMAX_INPUT_SIZE);
|
|
|
- len = strlen((char *)pcCommandInput);
|
|
|
if(len >= MAX_WEB_LOGIN_LEN){
|
|
|
strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
|
|
|
- auth_tlnt_srvr_param[num_conn].telnetState = TELNET_CMD;
|
|
|
+ s->telnetState = TELNET_CMD;
|
|
|
}
|
|
|
else{
|
|
|
- strncpy(password2, (char *)pcCommandInput, len);
|
|
|
+ strncpy(password2, s->buf, len);
|
|
|
|
|
|
if (strncmp(password, password2, MAX_WEB_PASSWD_LEN) == 0) {
|
|
|
memcpy(sSettings.sAuth[id_change_pwd].password, password, 11);
|
|
@@ -703,12 +890,12 @@ static portBASE_TYPE FreeRTOS_ChangePWDProcess( const int8_t * const pcCommandIn
|
|
|
HTTP_SaveSettings();
|
|
|
log_event_data(LOG_PSW_CHANGE, name_login_telnet);
|
|
|
strcpy( ( char * ) pcWriteBuffer, "\r\nПароль успешно изменен\r\n>" );
|
|
|
- auth_tlnt_srvr_param[num_conn].telnetState = TELNET_CMD;
|
|
|
+ s->telnetState = TELNET_CMD;
|
|
|
xReturn = pdTRUE;
|
|
|
}
|
|
|
else{
|
|
|
strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка при вводе нового пароля\r\n>" );
|
|
|
- auth_tlnt_srvr_param[num_conn].telnetState = TELNET_CMD;
|
|
|
+ s->telnetState = TELNET_CMD;
|
|
|
}
|
|
|
}
|
|
|
}
|