|  | @@ -163,10 +163,8 @@ typedef struct{
 | 
	
		
			
				|  |  |  	char prev_cmd[cmdMAX_INPUT_SIZE];
 | 
	
		
			
				|  |  |  	unsigned char optdata[cmdMAX_INPUT_SIZE];
 | 
	
		
			
				|  |  |  	uint8_t optlen;
 | 
	
		
			
				|  |  | -	state_telnet_server_t telnetState;
 | 
	
		
			
				|  |  |  	user_level_t telnet_code_auth;
 | 
	
		
			
				|  |  | -	char login[MAX_WEB_LOGIN_LEN];
 | 
	
		
			
				|  |  | -	uint8_t login_err;
 | 
	
		
			
				|  |  | +	uint8_t login_err;	// the number of failed password entry attempts
 | 
	
		
			
				|  |  |  	uint8_t num_connect;
 | 
	
		
			
				|  |  |  	bool active_conn;
 | 
	
		
			
				|  |  |  	bool flag_telnet_ip_option;
 | 
	
	
		
			
				|  | @@ -222,6 +220,15 @@ static void sendopt(telnetd_state_t *s, u8_t code, u8_t option)
 | 
	
		
			
				|  |  |  	send( s->num_connect, buf, 3, 0 );
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static void sendopt_cli(cli_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 );
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void sendsubopt(telnetd_state_t *s, u8_t code, u8_t *option, u8_t len)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	unsigned char buf[cmdMAX_INPUT_SIZE+3];
 | 
	
	
		
			
				|  | @@ -261,7 +268,7 @@ void parseopt(telnetd_state_t *ts, uint8_t code, uint8_t option)
 | 
	
		
			
				|  |  |  			ts->flag_telnet_ip_option = true;
 | 
	
		
			
				|  |  |  			sendopt(ts, TELNET_WILL, TELOPT_TIMING_MARK);
 | 
	
		
			
				|  |  |  			sendopt(ts, TELNET_MARK, 0);
 | 
	
		
			
				|  |  | -			if(ts->telnetState != TELNET_CHANGE_PWD && ts->telnetState != TELNET_CHANGE_PWD_ACK)
 | 
	
		
			
				|  |  | +			if(ts->cli_state->input_state != CLI_CHANGE_PWD && ts->cli_state->input_state != CLI_CHANGE_PWD_ACK)
 | 
	
		
			
				|  |  |  				send( ts->num_connect, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
 | 
	
		
			
				|  |  |  			break;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -322,6 +329,102 @@ static void parseoptdat(telnetd_state_t *ts, int option, unsigned char *data, ui
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +extern int8_t cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +portBASE_TYPE FreeRTOS_CLIAuthProcess( int8_t * pcWriteBuffer, cli_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];
 | 
	
		
			
				|  |  | +	char password[cmdMAX_INPUT_SIZE] = { 0 };
 | 
	
		
			
				|  |  | +	const int8_t * const pcPSWHeader = ( int8_t * ) "\r\npassword:";
 | 
	
		
			
				|  |  | +	const int8_t * const pcLoginHeader = ( int8_t * ) "\r\nlogin:";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	printf("CAP buf: %s\r\n", s->buf);
 | 
	
		
			
				|  |  | +	memset(pcWriteBuffer, 0, configCOMMAND_INT_MAX_OUTPUT_SIZE);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	switch(s->input_state){
 | 
	
		
			
				|  |  | +	case CLI_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_cli(s, TELNET_WILL, TELOPT_ECHO);
 | 
	
		
			
				|  |  | +			strncpy( ( char * ) pcWriteBuffer, ( const char * ) pcPSWHeader, strlen( ( char * ) pcPSWHeader ) );
 | 
	
		
			
				|  |  | +			s->input_state = CLI_AUTH_PASSW;
 | 
	
		
			
				|  |  | +			xReturn = pdTRUE;
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			xReturn = pdFALSE;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +	case CLI_AUTH_PASSW:
 | 
	
		
			
				|  |  | +		sendopt_cli(s, TELNET_WONT, TELOPT_ECHO);
 | 
	
		
			
				|  |  | +		// TODO unify with cli_auth_user
 | 
	
		
			
				|  |  | +		memset(name_login_telnet, 0, 50);
 | 
	
		
			
				|  |  | +		memset(password, 0, MAX_WEB_PASSWD_LEN);
 | 
	
		
			
				|  |  | +		len = strlen(s->buf);
 | 
	
		
			
				|  |  | +		strncpy(password, s->buf, 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, s->login, MAX_WEB_LOGIN_LEN) == 0) &&
 | 
	
		
			
				|  |  | +				(strncmp(WebPassword, password, MAX_WEB_PASSWD_LEN) == 0)) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +				/* Login and pass are valid */
 | 
	
		
			
				|  |  | +				s->user_id = user_id;
 | 
	
		
			
				|  |  | +				s->login_err = 0;
 | 
	
		
			
				|  |  | +				strcpy( ( char * ) pcWriteBuffer, "\r\nАвторизация успешно пройдена\r\n>" );
 | 
	
		
			
				|  |  | +				s->input_state = CLI_CMD;
 | 
	
		
			
				|  |  | +				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);
 | 
	
		
			
				|  |  | +				xReturn = pdTRUE;
 | 
	
		
			
				|  |  | +				break;
 | 
	
		
			
				|  |  | +			} else {
 | 
	
		
			
				|  |  | +				xReturn = pdFALSE;
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +	default:
 | 
	
		
			
				|  |  | +		// called auth when already authorized
 | 
	
		
			
				|  |  | +		xReturn = pdFALSE;
 | 
	
		
			
				|  |  | +		s->input_state = CLI_AUTH;
 | 
	
		
			
				|  |  | +		return xReturn;
 | 
	
		
			
				|  |  | +		break;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (xReturn == pdFALSE){
 | 
	
		
			
				|  |  | +		s->input_state = CLI_AUTH;
 | 
	
		
			
				|  |  | +		if (s->login_err < 4){
 | 
	
		
			
				|  |  | +			s->login_err ++;
 | 
	
		
			
				|  |  | +			strcpy( ( char * ) pcWriteBuffer, "\r\nОшибка авторизации\r\n" );
 | 
	
		
			
				|  |  | +			strncat( ( char * ) pcWriteBuffer, ( const char * ) pcLoginHeader, strlen( ( char * ) pcLoginHeader ) );
 | 
	
		
			
				|  |  | +			xReturn = pdTRUE;
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			// password entry tries exceeded
 | 
	
		
			
				|  |  | +			s->login_err = 0;
 | 
	
		
			
				|  |  | +			xReturn = pdFALSE;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		printf("login error, errors so far: %d\r\n", s->login_err);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return xReturn;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /*-----------------------------------------------------------------------------------*/
 | 
	
		
			
				|  |  |  static void newdata(telnetd_state_t *s)
 | 
	
		
			
				|  |  |  {
 | 
	
	
		
			
				|  | @@ -381,11 +484,11 @@ static void newdata(telnetd_state_t *s)
 | 
	
		
			
				|  |  |  		if(c == TELNET_IAC) {
 | 
	
		
			
				|  |  |  			s->state = STATE_IAC;
 | 
	
		
			
				|  |  |  		} else {
 | 
	
		
			
				|  |  | +			// incoming user input
 | 
	
		
			
				|  |  |  			cli_getchar(s->cli_state, c);
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		break;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /*-----------------------------------------------------------*/
 | 
	
	
		
			
				|  | @@ -599,7 +702,6 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 | 
	
		
			
				|  |  |  								if(auth_tlnt_srvr_param[k].active_conn == false && (cli_state = alloc_state())){
 | 
	
		
			
				|  |  |  									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;
 | 
	
		
			
				|  |  |  									cli_state->num_connect = new_sd;
 | 
	
		
			
				|  |  |  									cli_state->send = cli_send;
 | 
	
	
		
			
				|  | @@ -659,7 +761,6 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  					for(cur_cnt = 0; cur_cnt < NUMBER_TELNET_CONNECT; cur_cnt ++){
 | 
	
		
			
				|  |  |  						if(auth_tlnt_srvr_param[cur_cnt].num_connect == i){
 | 
	
		
			
				|  |  | -							//telnetState = auth_tlnt_srvr_param[cur_cnt].telnetState;
 | 
	
		
			
				|  |  |  							const user_level_t telnet_code_auth = auth_tlnt_srvr_param[cur_cnt].telnet_code_auth;
 | 
	
		
			
				|  |  |  							switch (telnet_code_auth) {
 | 
	
		
			
				|  |  |  							  case ADMIN:
 | 
	
	
		
			
				|  | @@ -714,7 +815,6 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 | 
	
		
			
				|  |  |  						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;
 | 
	
		
			
				|  |  |  						auth_tlnt_srvr_param[cur_cnt].telnet_code_auth = USER;
 | 
	
		
			
				|  |  |  						auth_tlnt_srvr_param[cur_cnt].flag_telnet_ip_option = false;
 | 
	
		
			
				|  |  |  						cnt_conn -= 1;
 |