Browse Source

telnet: do not echo the user's password during login

Sergey Alirzaev 5 years ago
parent
commit
9d0f14e59d
4 changed files with 110 additions and 115 deletions
  1. 108 8
      modules/Telnet_Server/telnet_server.c
  2. 1 11
      modules/Telnet_Server/telnet_server.h
  3. 1 92
      modules/cli/cli.c
  4. 0 4
      modules/cli/cli.h

+ 108 - 8
modules/Telnet_Server/telnet_server.c

@@ -163,10 +163,8 @@ typedef struct{
 	char prev_cmd[cmdMAX_INPUT_SIZE];
 	char prev_cmd[cmdMAX_INPUT_SIZE];
 	unsigned char optdata[cmdMAX_INPUT_SIZE];
 	unsigned char optdata[cmdMAX_INPUT_SIZE];
 	uint8_t optlen;
 	uint8_t optlen;
-	state_telnet_server_t telnetState;
 	user_level_t telnet_code_auth;
 	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;
 	uint8_t num_connect;
 	bool active_conn;
 	bool active_conn;
 	bool flag_telnet_ip_option;
 	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 );
 	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)
 static void sendsubopt(telnetd_state_t *s, u8_t code, u8_t *option, u8_t len)
 {
 {
 	unsigned char buf[cmdMAX_INPUT_SIZE+3];
 	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;
 			ts->flag_telnet_ip_option = true;
 			sendopt(ts, TELNET_WILL, TELOPT_TIMING_MARK);
 			sendopt(ts, TELNET_WILL, TELOPT_TIMING_MARK);
 			sendopt(ts, TELNET_MARK, 0);
 			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 );
 				send( ts->num_connect, pcEndOfCommandOutputString, strlen( ( const char * ) pcEndOfCommandOutputString ), 0 );
 			break;
 			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)
 static void newdata(telnetd_state_t *s)
 {
 {
@@ -381,11 +484,11 @@ static void newdata(telnetd_state_t *s)
 		if(c == TELNET_IAC) {
 		if(c == TELNET_IAC) {
 			s->state = STATE_IAC;
 			s->state = STATE_IAC;
 		} else {
 		} else {
+			// incoming user input
 			cli_getchar(s->cli_state, c);
 			cli_getchar(s->cli_state, c);
 		}
 		}
 		break;
 		break;
 	}
 	}
-
 }
 }
 
 
 /*-----------------------------------------------------------*/
 /*-----------------------------------------------------------*/
@@ -599,7 +702,6 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 								if(auth_tlnt_srvr_param[k].active_conn == false && (cli_state = alloc_state())){
 								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].active_conn = true;
 									auth_tlnt_srvr_param[k].num_connect = new_sd;
 									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;
 									auth_tlnt_srvr_param[k].state = STATE_NORMAL;
 									cli_state->num_connect = new_sd;
 									cli_state->num_connect = new_sd;
 									cli_state->send = cli_send;
 									cli_state->send = cli_send;
@@ -659,7 +761,6 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
 
 
 					for(cur_cnt = 0; cur_cnt < NUMBER_TELNET_CONNECT; cur_cnt ++){
 					for(cur_cnt = 0; cur_cnt < NUMBER_TELNET_CONNECT; cur_cnt ++){
 						if(auth_tlnt_srvr_param[cur_cnt].num_connect == i){
 						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;
 							const user_level_t telnet_code_auth = auth_tlnt_srvr_param[cur_cnt].telnet_code_auth;
 							switch (telnet_code_auth) {
 							switch (telnet_code_auth) {
 							  case ADMIN:
 							  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].state = STATE_NORMAL;
 						auth_tlnt_srvr_param[cur_cnt].num_connect = 0;
 						auth_tlnt_srvr_param[cur_cnt].num_connect = 0;
 						auth_tlnt_srvr_param[cur_cnt].active_conn = false;
 						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].telnet_code_auth = USER;
 						auth_tlnt_srvr_param[cur_cnt].flag_telnet_ip_option = false;
 						auth_tlnt_srvr_param[cur_cnt].flag_telnet_ip_option = false;
 						cnt_conn -= 1;
 						cnt_conn -= 1;

+ 1 - 11
modules/Telnet_Server/telnet_server.h

@@ -16,19 +16,9 @@
 /*Number of connection*/
 /*Number of connection*/
 #define NUMBER_TELNET_CONNECT		5
 #define NUMBER_TELNET_CONNECT		5
 
 
-typedef enum{
-	TELNET_AUTH = 0,
-	TELNET_AUTH_PASSW,
-	TELNET_CMD,
-	TELNET_CHANGE_PWD,
-	TELNET_CHANGE_PWD_ACK
-}state_telnet_server_t;
-
-
 void telnet_server_init(void);
 void telnet_server_init(void);
-
 void telnet_server_close(void);
 void telnet_server_close(void);
-
 void telnet_server_port_change(void);
 void telnet_server_port_change(void);
+portBASE_TYPE FreeRTOS_CLIAuthProcess( int8_t * pcWriteBuffer, cli_state_t *s);
 
 
 #endif /* TELNET_SERVER_H_ */
 #endif /* TELNET_SERVER_H_ */

+ 1 - 92
modules/cli/cli.c

@@ -12,6 +12,7 @@
 #include "log.h"
 #include "log.h"
 #include "web_params_api.h"
 #include "web_params_api.h"
 #include "tinystdio.h"
 #include "tinystdio.h"
+#include "telnet_server.h"
 
 
 #define ISO_nl       0x0a
 #define ISO_nl       0x0a
 #define ISO_cr       0x0d
 #define ISO_cr       0x0d
@@ -47,98 +48,6 @@ void SensorInfoTimerCallback(TimerHandle_t pxTimer) {
 	xTimerStart(cli_states[num_timer].RepeatSensorInfoTimer, 0);
 	xTimerStart(cli_states[num_timer].RepeatSensorInfoTimer, 0);
 }
 }
 
 
-static 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:";
-
-	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(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(s, TELNET_WONT, TELOPT_ECHO);
-		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:
-		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{
-			s->login_err = 0;
-			xReturn = pdFALSE;
-		}
-	}
-
-	return xReturn;
-}
-
 static portBASE_TYPE FreeRTOS_ChangePWDProcess( int8_t * pcWriteBuffer, cli_state_t *s)
 static portBASE_TYPE FreeRTOS_ChangePWDProcess( int8_t * pcWriteBuffer, cli_state_t *s)
 {
 {
 	portBASE_TYPE xReturn = pdTRUE;
 	portBASE_TYPE xReturn = pdTRUE;

+ 0 - 4
modules/cli/cli.h

@@ -38,7 +38,6 @@ typedef enum {
 typedef struct {
 typedef struct {
 	TimerHandle_t RepeatSensorInfoTimer;
 	TimerHandle_t RepeatSensorInfoTimer;
 	conn_state_t state;
 	conn_state_t state;
-//	uint8_t code;
 	char buf[cmdMAX_INPUT_SIZE];
 	char buf[cmdMAX_INPUT_SIZE];
 	uint_fast8_t bufptr;
 	uint_fast8_t bufptr;
 	char prev_cmd[cmdMAX_INPUT_SIZE];
 	char prev_cmd[cmdMAX_INPUT_SIZE];
@@ -48,10 +47,7 @@ typedef struct {
 	user_level_t user_id;
 	user_level_t user_id;
 	char login[MAX_WEB_LOGIN_LEN];
 	char login[MAX_WEB_LOGIN_LEN];
 	uint8_t login_err;	// the number of failed password entry attempts
 	uint8_t login_err;	// the number of failed password entry attempts
-//	bool active_conn;
 	bool flag_telnet_ip_option;	// wtf is this
 	bool flag_telnet_ip_option;	// wtf is this
-
-	//send( cli_states[num_timer].num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
 	void (*send)(intptr_t fd, const char *str, unsigned len);
 	void (*send)(intptr_t fd, const char *str, unsigned len);
 	intptr_t num_connect;	// fd
 	intptr_t num_connect;	// fd
 } cli_state_t;
 } cli_state_t;