|
@@ -85,21 +85,95 @@
|
|
|
#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_DISPLAY_POS 35 // Linemode (RFC1184)
|
|
|
#define TELOPT_AUTHENTICATION 37 // Authentication (RFC1416)
|
|
|
-
|
|
|
+#define TELOPT_NEW_ENV_OPTION 39 // Authentication (RFC1416)
|
|
|
+
|
|
|
+//Sub option for LINEMODE
|
|
|
+
|
|
|
+#define LINEMODE_MODE 1
|
|
|
+#define LINEMODE_EDIT 1
|
|
|
+#define LINEMODE_TRAPSIG 2
|
|
|
+#define LINEMODE_MODE_ACK 4
|
|
|
+#define LINEMODE_SOFT_TAB 8
|
|
|
+#define LINEMODE_LIT_ECHO 16
|
|
|
+#define LINEMODE_FORWARDMASK 2
|
|
|
+#define LINEMODE_SLC 3
|
|
|
+#define LINEMODE_SLC_SYNCH 1
|
|
|
+#define LINEMODE_SLC_BRK 2
|
|
|
+#define LINEMODE_SLC_IP 3
|
|
|
+#define LINEMODE_SLC_AO 4
|
|
|
+#define LINEMODE_SLC_AYT 5
|
|
|
+#define LINEMODE_SLC_EOR 6
|
|
|
+#define LINEMODE_SLC_ABORT 7
|
|
|
+#define LINEMODE_SLC_EOF 8
|
|
|
+#define LINEMODE_SLC_SUSP 9
|
|
|
+#define LINEMODE_SLC_EC 10
|
|
|
+#define LINEMODE_SLC_EL 11
|
|
|
+#define LINEMODE_SLC_EW 12
|
|
|
+#define LINEMODE_SLC_RP 13
|
|
|
+#define LINEMODE_SLC_LNEXT 14
|
|
|
+#define LINEMODE_SLC_XON 15
|
|
|
+#define LINEMODE_SLC_XOFF 16
|
|
|
+#define LINEMODE_SLC_FORW1 17
|
|
|
+#define LINEMODE_SLC_FORW2 18
|
|
|
+#define LINEMODE_SLC_MCL 19
|
|
|
+#define LINEMODE_SLC_MCR 20
|
|
|
+#define LINEMODE_SLC_MCWL 21
|
|
|
+#define LINEMODE_SLC_MCWR 22
|
|
|
+#define LINEMODE_SLC_MCBOL 23
|
|
|
+#define LINEMODE_SLC_MCEOL 24
|
|
|
+#define LINEMODE_SLC_INSRT 25
|
|
|
+#define LINEMODE_SLC_OVER 26
|
|
|
+#define LINEMODE_SLC_ECR 27
|
|
|
+#define LINEMODE_SLC_EWR 28
|
|
|
+#define LINEMODE_SLC_EBOL 29
|
|
|
+#define LINEMODE_SLC_EEOL 30
|
|
|
+
|
|
|
+#define LINEMODE_SLC_DEFAULT 3
|
|
|
+#define LINEMODE_SLC_VALUE 2
|
|
|
+#define LINEMODE_SLC_CANTCHANGE 1
|
|
|
+#define LINEMODE_SLC_NOSUPPORT 0
|
|
|
+#define LINEMODE_SLC_LEVELBITS 3
|
|
|
+
|
|
|
+#define LINEMODE_SLC_ACK 128
|
|
|
+#define LINEMODE_SLC_FLUSHIN 64
|
|
|
+#define LINEMODE_SLC_FLUSHOUT 32
|
|
|
+#define LINEMODE_EOF 236
|
|
|
+#define LINEMODE_SUSP 237
|
|
|
+#define LINEMODE_ABORT 238
|
|
|
|
|
|
/* Repeat Login timeout, 1 seconds */
|
|
|
-#define REPEAT_SENSOR_INFO_TIME configTICK_RATE_HZ*1*1
|
|
|
+#define REPEAT_SENSOR_INFO_TIME configTICK_RATE_HZ*5*1
|
|
|
|
|
|
/* Set option to drop old connection if the new one is accepted */
|
|
|
#define TCP_DROP_PREV_CONNECTION 0
|
|
|
|
|
|
+/**
|
|
|
+ * A telnet connection structure.
|
|
|
+ */
|
|
|
+typedef struct{
|
|
|
+ TimerHandle_t RepeatSensorInfoTimer;
|
|
|
+ uint8_t state;
|
|
|
+ uint8_t code;
|
|
|
+ char buf[cmdMAX_INPUT_SIZE];
|
|
|
+ char bufptr;
|
|
|
+ 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 num_connect;
|
|
|
+ bool active_conn;
|
|
|
+ bool flagWhiteListTelnet;
|
|
|
+}telnetd_state_t;
|
|
|
+
|
|
|
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;
|
|
|
-
|
|
|
state_telnet_server_t telnetState = TELNET_AUTH;
|
|
|
uint8_t id_change_pwd = 0;
|
|
|
user_level_t telnet_code_auth = USER;
|
|
@@ -192,6 +266,7 @@ static void telnetd_input(telnetd_state_t *s)
|
|
|
/* Ensure there is not a string lingering in
|
|
|
the output buffer. */
|
|
|
pcOutputString[ 0 ] = 0x00;
|
|
|
+ telnetState = s->telnetState;
|
|
|
xReturned = FreeRTOS_CLIProcessCommand( s->buf, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
|
|
|
s->telnetState = telnetState;
|
|
|
send( s->num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
|
|
@@ -201,7 +276,7 @@ static void telnetd_input(telnetd_state_t *s)
|
|
|
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);
|
|
|
+ xTimerStart(s->RepeatSensorInfoTimer, 0);
|
|
|
}
|
|
|
else{
|
|
|
|
|
@@ -230,9 +305,12 @@ static void telnetd_input(telnetd_state_t *s)
|
|
|
/*-----------------------------------------------------------------------------------*/
|
|
|
static void getchar(telnetd_state_t *s)
|
|
|
{
|
|
|
- if(type_term == 1){
|
|
|
+ if(type_term == 1 && s->telnetState != TELNET_AUTH_PASSW){
|
|
|
send( s->num_connect, &s->buf[s->bufptr], 1, 0 );
|
|
|
}
|
|
|
+ else if(s->telnetState == TELNET_AUTH_PASSW){
|
|
|
+ send( s->num_connect, " ", 1, 0 );
|
|
|
+ }
|
|
|
|
|
|
|
|
|
if(s->buf[s->bufptr] == ISO_nl ||
|
|
@@ -273,6 +351,18 @@ static void sendopt(telnetd_state_t *s, u8_t code, u8_t 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];
|
|
|
+ buf[0] = TELNET_IAC;
|
|
|
+ buf[1] = TELNET_SB;
|
|
|
+ buf[2] = code;
|
|
|
+ memcpy(&buf[3], option, len);
|
|
|
+ buf[len + 3] = TELNET_IAC;
|
|
|
+ buf[len + 4] = TELNET_SE;
|
|
|
+ send( s->num_connect, buf, (len + 5), 0 );
|
|
|
+}
|
|
|
+
|
|
|
void parseopt(telnetd_state_t *ts, uint8_t code, uint8_t option)
|
|
|
{
|
|
|
|
|
@@ -288,11 +378,17 @@ void parseopt(telnetd_state_t *ts, uint8_t code, uint8_t option)
|
|
|
case TELOPT_SUPPRESS_GO_AHEAD:
|
|
|
case TELOPT_LINEMODE:
|
|
|
case TELOPT_NAWS:
|
|
|
+ case TELOPT_DISPLAY_POS:
|
|
|
+ case TELOPT_NEW_ENV_OPTION:
|
|
|
+ case TELOPT_TERMINAL_SPEED:
|
|
|
+ case TELOPT_TERMINAL_TYPE:
|
|
|
+ case TELOPT_STATUS:
|
|
|
+ case TELOPT_TOGGLE_FLOW_CONTROL:
|
|
|
break;
|
|
|
|
|
|
case TELOPT_TIMING_MARK:
|
|
|
-
|
|
|
- xTimerStop(RepeatSensorInfoTimer, 0);
|
|
|
+ memset(ts->prev_cmd, 0, cmdMAX_INPUT_SIZE );
|
|
|
+ xTimerStop(ts->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)
|
|
@@ -311,6 +407,10 @@ void parseopt(telnetd_state_t *ts, uint8_t code, uint8_t option)
|
|
|
|
|
|
static void parseoptdat(telnetd_state_t *ts, int option, unsigned char *data, uint8_t len) {
|
|
|
|
|
|
+ uint8_t subopt = 0;
|
|
|
+ uint8_t subopt_val = 0;
|
|
|
+ uint8_t sub_opt_data[2] = {LINEMODE_MODE, LINEMODE_EDIT};
|
|
|
+
|
|
|
switch (option) {
|
|
|
case TELOPT_NAWS:
|
|
|
break;
|
|
@@ -320,6 +420,35 @@ static void parseoptdat(telnetd_state_t *ts, int option, unsigned char *data, ui
|
|
|
|
|
|
case TELOPT_TERMINAL_TYPE:
|
|
|
break;
|
|
|
+ case TELOPT_LINEMODE:
|
|
|
+ subopt = data[0];
|
|
|
+ switch (subopt) {
|
|
|
+ case LINEMODE_SLC:
|
|
|
+ if(data[2] & LINEMODE_SLC_ACK){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ sendsubopt(ts, option, sub_opt_data, 2);
|
|
|
+ for(uint8_t i = 1; i < len; i += 3){
|
|
|
+ subopt_val = data[i];
|
|
|
+ switch (subopt_val) {
|
|
|
+ case LINEMODE_SLC_IP:
|
|
|
+ data[i+1] = LINEMODE_SLC_VALUE | LINEMODE_SLC_FLUSHIN | LINEMODE_SLC_FLUSHOUT | LINEMODE_SLC_ACK;
|
|
|
+ break;
|
|
|
+ case LINEMODE_SLC_XON:
|
|
|
+ case LINEMODE_SLC_XOFF:
|
|
|
+ case LINEMODE_SLC_EC:
|
|
|
+ data[i+1] = LINEMODE_SLC_VALUE | LINEMODE_SLC_ACK;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ data[i+1] = LINEMODE_SLC_NOSUPPORT;
|
|
|
+ data[i+2] = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sendsubopt(ts, option, data, len);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -365,17 +494,19 @@ static void newdata(telnetd_state_t *s)
|
|
|
break;
|
|
|
|
|
|
case STATE_OPTDAT:
|
|
|
- if (c == TELNET_IAC) {
|
|
|
- s->state = STATE_SE;
|
|
|
+ if (c == TELNET_SE && s->optdata[s->optlen-1] == TELNET_IAC) {
|
|
|
+ parseoptdat(s, s->code, s->optdata, (s->optlen-1));
|
|
|
+ s->state = STATE_NORMAL;
|
|
|
+ //s->state = STATE_SE;
|
|
|
} else if (s->optlen < sizeof(s->optdata)) {
|
|
|
s->optdata[s->optlen++] = c;
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
- case STATE_SE:
|
|
|
+ /*case STATE_SE:
|
|
|
if (c == TELNET_SE) parseoptdat(s, s->code, s->optdata, s->optlen);
|
|
|
s->state = STATE_NORMAL;
|
|
|
- break;
|
|
|
+ break;*/
|
|
|
case STATE_NORMAL:
|
|
|
if(c == TELNET_IAC) {
|
|
|
s->state = STATE_IAC;
|
|
@@ -602,11 +733,11 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
|
|
|
#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);
|
|
|
+ vTaskDelay(10);
|
|
|
}
|
|
|
- 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_SUPPRESS_GO_AHEAD);
|
|
|
sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_LINEMODE);
|
|
|
+ sendopt(&auth_tlnt_srvr_param[k], TELNET_DO, TELOPT_ECHO);
|
|
|
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]);
|
|
@@ -703,11 +834,16 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
|
|
|
/* based on the bits that are still turned on in */
|
|
|
/* the master set. */
|
|
|
if (auth_tlnt_srvr_param[cur_cnt].state == STATE_CLOSE) {
|
|
|
+ memset(auth_tlnt_srvr_param[cur_cnt].buf, 0, cmdMAX_INPUT_SIZE);
|
|
|
+ memset(auth_tlnt_srvr_param[cur_cnt].prev_cmd, 0, cmdMAX_INPUT_SIZE);
|
|
|
+ memset(auth_tlnt_srvr_param[cur_cnt].optdata, 0, cmdMAX_INPUT_SIZE);
|
|
|
+ auth_tlnt_srvr_param[cur_cnt].optlen = 0;
|
|
|
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;
|
|
|
+ xTimerStop(auth_tlnt_srvr_param[cur_cnt].RepeatSensorInfoTimer, 0);
|
|
|
cnt_conn -= 1;
|
|
|
closesocket(i);
|
|
|
FD_CLR(i, &master_set);
|
|
@@ -725,33 +861,39 @@ void vBasicSocketsCommandInterpreterTask( void *pvParameters )
|
|
|
|
|
|
void telnet_server_init(void) {
|
|
|
for(uint8_t i = 0; i < NUMBER_TELNET_CONNECT; i++){
|
|
|
+ memset(auth_tlnt_srvr_param[i].buf, 0, cmdMAX_INPUT_SIZE);
|
|
|
+ memset(auth_tlnt_srvr_param[i].prev_cmd, 0, cmdMAX_INPUT_SIZE);
|
|
|
+ memset(auth_tlnt_srvr_param[i].optdata, 0, cmdMAX_INPUT_SIZE);
|
|
|
+ auth_tlnt_srvr_param[i].optlen = 0;
|
|
|
auth_tlnt_srvr_param[i].num_connect = 0;
|
|
|
auth_tlnt_srvr_param[i].active_conn = false;
|
|
|
auth_tlnt_srvr_param[i].telnetState = TELNET_AUTH;
|
|
|
auth_tlnt_srvr_param[i].telnet_code_auth = USER;
|
|
|
+ auth_tlnt_srvr_param[i].RepeatSensorInfoTimer = xTimerCreate("SensorInfoTmr", REPEAT_SENSOR_INFO_TIME, pdFALSE, ( void * ) i, SensorInfoTimerCallback);
|
|
|
}
|
|
|
vRegisterCLICommands();
|
|
|
xTaskCreate(vBasicSocketsCommandInterpreterTask, ( char * ) "vBasicSocketsCommandInterpreterTask", 8*configMINIMAL_STACK_SIZE , NULL, tskIDLE_PRIORITY + 1, NULL);
|
|
|
- RepeatSensorInfoTimer = xTimerCreate("SensorInfoTmr", REPEAT_SENSOR_INFO_TIME, pdFALSE, ( void * ) 0, SensorInfoTimerCallback);
|
|
|
}
|
|
|
|
|
|
void SensorInfoTimerCallback(TimerHandle_t pxTimer) {
|
|
|
portBASE_TYPE xReturned = pdTRUE;
|
|
|
-
|
|
|
+ uint8_t num_timer;
|
|
|
+ for(uint8_t i = 0; i < NUMBER_TELNET_CONNECT; i ++){
|
|
|
+ if(pxTimer == auth_tlnt_srvr_param[i].RepeatSensorInfoTimer){
|
|
|
+ num_timer = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
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 );
|
|
|
- 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 );
|
|
|
- }
|
|
|
- }
|
|
|
+ send( auth_tlnt_srvr_param[num_timer].num_connect, pcOutputString, strlen( ( const char * ) pcOutputString ), 0 );
|
|
|
|
|
|
} while( xReturned != pdFALSE );
|
|
|
- xTimerStart(RepeatSensorInfoTimer, 0);
|
|
|
+ xTimerStart(auth_tlnt_srvr_param[num_timer].RepeatSensorInfoTimer, 0);
|
|
|
}
|
|
|
|
|
|
static portBASE_TYPE FreeRTOS_CLIAuthProcess( int8_t * pcWriteBuffer, telnetd_state_t *s )
|