|
@@ -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;
|