@@ -58,6 +58,7 @@ struct webrepl_file {
5858} __attribute__((packed ));
5959
6060enum { PUT_FILE = 1 , GET_FILE , LIST_DIR };
61+ enum { STATE_PASSWD , STATE_NORMAL };
6162
6263typedef struct _mp_obj_webrepl_t {
6364 mp_obj_base_t base ;
@@ -69,6 +70,12 @@ typedef struct _mp_obj_webrepl_t {
6970 mp_obj_t cur_file ;
7071} mp_obj_webrepl_t ;
7172
73+ // These get passed to functions which aren't force-l32, so can't be const
74+ STATIC char passwd_prompt [] = "Password: " ;
75+ STATIC char connected_prompt [] = "\r\nWebREPL connected\r\n>>> " ;
76+ STATIC char denied_prompt [] = "\r\nAccess denied\r\n" ;
77+
78+ STATIC char webrepl_passwd [10 ];
7279
7380static inline void close_meth (mp_obj_t stream ) {
7481 mp_obj_t dest [2 ];
@@ -84,6 +91,13 @@ STATIC void write_webrepl(mp_obj_t websock, const void *buf, size_t len) {
8491 sock_stream -> ioctl (websock , MP_STREAM_SET_DATA_OPTS , old_opts , & err );
8592}
8693
94+ #define SSTR (s ) s, sizeof(s) - 1
95+ STATIC void write_webrepl_str (mp_obj_t websock , const char * str , int sz ) {
96+ int err ;
97+ const mp_stream_p_t * sock_stream = mp_get_stream_raise (websock , MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL );
98+ sock_stream -> write (websock , str , sz , & err );
99+ }
100+
87101STATIC void write_webrepl_resp (mp_obj_t websock , uint16_t code ) {
88102 char buf [4 ] = {'W' , 'B' , code & 0xff , code >> 8 };
89103 write_webrepl (websock , buf , sizeof (buf ));
@@ -98,6 +112,8 @@ STATIC mp_obj_t webrepl_make_new(const mp_obj_type_t *type, size_t n_args, size_
98112 o -> sock = args [0 ];
99113 o -> hdr_to_recv = sizeof (struct webrepl_file );
100114 o -> data_to_recv = 0 ;
115+ o -> state = STATE_PASSWD ;
116+ write_webrepl_str (args [0 ], SSTR (passwd_prompt ));
101117 return o ;
102118}
103119
@@ -168,6 +184,27 @@ STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int
168184 if (out_sz == 0 || out_sz == MP_STREAM_ERROR ) {
169185 return out_sz ;
170186 }
187+
188+ if (self -> state == STATE_PASSWD ) {
189+ char c = * (char * )buf ;
190+ if (c == '\r' || c == '\n' ) {
191+ self -> hdr .fname [self -> data_to_recv ] = 0 ;
192+ DEBUG_printf ("webrepl: entered password: %s\n" , self -> hdr .fname );
193+
194+ if (strcmp (self -> hdr .fname , webrepl_passwd ) != 0 ) {
195+ write_webrepl_str (self -> sock , SSTR (denied_prompt ));
196+ return 0 ;
197+ }
198+
199+ self -> state = STATE_NORMAL ;
200+ self -> data_to_recv = 0 ;
201+ write_webrepl_str (self -> sock , SSTR (connected_prompt ));
202+ } else if (self -> data_to_recv < 10 ) {
203+ self -> hdr .fname [self -> data_to_recv ++ ] = c ;
204+ }
205+ return -2 ;
206+ }
207+
171208 // If last read data belonged to text record (== REPL)
172209 int err ;
173210 if (sock_stream -> ioctl (self -> sock , MP_STREAM_GET_DATA_OPTS , 0 , & err ) == 1 ) {
@@ -239,10 +276,21 @@ STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int
239276
240277STATIC mp_uint_t webrepl_write (mp_obj_t self_in , const void * buf , mp_uint_t size , int * errcode ) {
241278 mp_obj_webrepl_t * self = self_in ;
279+ if (self -> state == STATE_PASSWD ) {
280+ // Don't forward output until passwd is entered
281+ return size ;
282+ }
242283 const mp_stream_p_t * stream_p = mp_get_stream_raise (self -> sock , MP_STREAM_OP_WRITE );
243284 return stream_p -> write (self -> sock , buf , size , errcode );
244285}
245286
287+ STATIC mp_obj_t webrepl_set_password (mp_obj_t passwd_in ) {
288+ const char * passwd = mp_obj_str_get_str (passwd_in );
289+ strncpy (webrepl_passwd , passwd , sizeof (webrepl_passwd ));
290+ return mp_const_none ;
291+ }
292+ STATIC MP_DEFINE_CONST_FUN_OBJ_1 (webrepl_set_password_obj , webrepl_set_password );
293+
246294STATIC const mp_map_elem_t webrepl_locals_dict_table [] = {
247295 { MP_OBJ_NEW_QSTR (MP_QSTR_read ), (mp_obj_t )& mp_stream_read_obj },
248296 { MP_OBJ_NEW_QSTR (MP_QSTR_write ), (mp_obj_t )& mp_stream_write_obj },
@@ -265,6 +313,7 @@ STATIC const mp_obj_type_t webrepl_type = {
265313STATIC const mp_map_elem_t webrepl_module_globals_table [] = {
266314 { MP_OBJ_NEW_QSTR (MP_QSTR___name__ ), MP_OBJ_NEW_QSTR (MP_QSTR_websocket ) },
267315 { MP_OBJ_NEW_QSTR (MP_QSTR__webrepl ), (mp_obj_t )& webrepl_type },
316+ { MP_OBJ_NEW_QSTR (MP_QSTR_password ), (mp_obj_t )& webrepl_set_password_obj },
268317};
269318
270319STATIC MP_DEFINE_CONST_DICT (webrepl_module_globals , webrepl_module_globals_table );
0 commit comments