@@ -732,6 +732,8 @@ static void dcc_chat_pass(int idx, char *buf, int atr)
732732 /* Turn echo back on for telnet sessions (send IAC WON'T ECHO). */
733733 if (dcc [idx ].status & STAT_TELNET )
734734 tputs (dcc [idx ].sock , TLN_IAC_C TLN_WONT_C TLN_ECHO_C "\n" , 4 );
735+ else if (dcc [idx ].status & STAT_WS )
736+ tputs (dcc [idx ].sock , WS_ECHO_ON , 1 );
735737 dcc_chatter (idx );
736738 }
737739 } else {
@@ -1292,11 +1294,18 @@ static void dcc_telnet(int idx, char *buf, int i)
12921294 */
12931295 if (!(tls_vfyclients & TLS_VERIFYCN ))
12941296 threaddata ()-> socklist [findsock (sock )].flags |= SOCK_VIRTUAL ;
1295- else if (ssl_handshake (dcc [i ].sock , TLS_LISTEN , tls_vfyclients ,
1296- LOG_MISC , NULL , NULL )) {
1297- killsock (dcc [i ].sock );
1298- lostdcc (i );
1299- return ;
1297+ else {
1298+ #ifdef TLS
1299+ if (!strcmp (dcc [idx ].nick , "(webui)" ))
1300+ ssl_cleanup (); /* reset ssl_ctx for websocket */
1301+ #endif /* TLS */
1302+ if (ssl_handshake (dcc [i ].sock , TLS_LISTEN ,
1303+ strcmp (dcc [idx ].nick , "(webui)" ) ? tls_vfyclients : 0 ,
1304+ LOG_MISC , NULL , NULL )) {
1305+ killsock (dcc [i ].sock );
1306+ lostdcc (i );
1307+ return ;
1308+ }
13001309 }
13011310 }
13021311#endif
@@ -1310,12 +1319,68 @@ static void dcc_telnet(int idx, char *buf, int i)
13101319 dcc_dnshostbyip (& dcc [i ].sockname );
13111320}
13121321
1322+ /* we need this for dcc_telnet_hostresolved() could now branch to DCC_TABLE
1323+ * and for either branch we need to continue here
1324+ */
1325+ void dcc_telnet_hostresolved2 (int i , int idx ) {
1326+ int j , sock ;
1327+ char * userhost = dcc [idx ].host ; /* TODO: writing host back to userhost looks like back and forth copying */
1328+ /* Skip ident lookup if disabled */
1329+ if (identtimeout <= 0 ) {
1330+ dcc [i ].u .ident_sock = dcc [idx ].sock ;
1331+ dcc_telnet_got_ident (i , userhost );
1332+ return ;
1333+ }
1334+
1335+ changeover_dcc (i , & DCC_IDENTWAIT , 0 );
1336+ dcc [i ].timeval = now ;
1337+ dcc [i ].u .ident_sock = dcc [idx ].sock ;
1338+ sock = -1 ;
1339+ j = new_dcc (& DCC_IDENT , 0 );
1340+ if (j < 0 )
1341+ putlog (LOG_MISC , "*" , DCC_IDENTFAIL , dcc [i ].host , strerror (errno ));
1342+ else {
1343+ memcpy (& dcc [j ].sockname , & dcc [i ].sockname , sizeof (sockname_t ));
1344+ dcc [j ].sock = getsock (dcc [j ].sockname .family , 0 );
1345+ if (dcc [j ].sock >= 0 ) {
1346+ sockname_t name ;
1347+ name .addrlen = sizeof (name .addr );
1348+ if (getsockname (dcc [i ].sock , & name .addr .sa , & name .addrlen ) < 0 )
1349+ debug2 ("dcc: dcc_telnet_hostresolved(): getsockname() socket %ld error %s" , dcc [i ].sock , strerror (errno ));
1350+ setsnport (name , 0 );
1351+ if (bind (dcc [j ].sock , & name .addr .sa , name .addrlen ) < 0 )
1352+ debug2 ("dcc: dcc_telnet_hostresolved(): bind() socket %ld error %s" , dcc [j ].sock , strerror (errno ));
1353+ setsnport (dcc [j ].sockname , 113 );
1354+ if (connect (dcc [j ].sock , & dcc [j ].sockname .addr .sa ,
1355+ dcc [j ].sockname .addrlen ) < 0 && (errno != EINPROGRESS )) {
1356+ killsock (dcc [j ].sock );
1357+ lostdcc (j );
1358+ putlog (LOG_MISC , "*" , DCC_IDENTFAIL , dcc [i ].host , strerror (errno ));
1359+ j = 0 ;
1360+ }
1361+ sock = dcc [j ].sock ;
1362+ }
1363+ }
1364+ if (j < 0 ) {
1365+ dcc_telnet_got_ident (i , userhost );
1366+ return ;
1367+ }
1368+ dcc [j ].sock = sock ;
1369+ dcc [j ].port = 113 ;
1370+ dcc [j ].addr = dcc [i ].addr ;
1371+ strcpy (dcc [j ].host , dcc [i ].host );
1372+ strcpy (dcc [j ].nick , "*" );
1373+ dcc [j ].u .ident_sock = dcc [i ].sock ;
1374+ dcc [j ].timeval = now ;
1375+ dprintf (j , "%d, %d\n" , dcc [i ].port , dcc [idx ].port );
1376+ }
1377+
13131378static void dcc_telnet_hostresolved (int i )
13141379{
13151380 int idx ;
1316- int j = 0 , sock ;
13171381 char s [sizeof lasttelnethost ], * userhost ;
13181382
1383+ debug0 ("dcc_telnet_hostresolved()" );
13191384 strlcpy (dcc [i ].host , dcc [i ].u .dns -> host , UHOSTLEN );
13201385
13211386 for (idx = 0 ; idx < dcc_total ; idx ++ )
@@ -1374,54 +1439,16 @@ static void dcc_telnet_hostresolved(int i)
13741439 return ;
13751440 }
13761441
1377- /* Skip ident lookup if disabled */
1378- if ( identtimeout <= 0 ) {
1379- dcc [i ]. u . ident_sock = dcc [ idx ]. sock ;
1380- dcc_telnet_got_ident ( i , userhost );
1442+ #ifdef TLS
1443+ /* Skip ident lookup for webui http */
1444+ if (! strcmp ( dcc [idx ]. nick , "(webui)" )) {
1445+ webui_dcc_telnet_hostresolved ( i );
13811446 return ;
13821447 }
1448+ #endif /* TLS */
13831449
1384- changeover_dcc (i , & DCC_IDENTWAIT , 0 );
1385- dcc [i ].timeval = now ;
1386- dcc [i ].u .ident_sock = dcc [idx ].sock ;
1387- sock = -1 ;
1388- j = new_dcc (& DCC_IDENT , 0 );
1389- if (j < 0 )
1390- putlog (LOG_MISC , "*" , DCC_IDENTFAIL , dcc [i ].host , strerror (errno ));
1391- else {
1392- memcpy (& dcc [j ].sockname , & dcc [i ].sockname , sizeof (sockname_t ));
1393- dcc [j ].sock = getsock (dcc [j ].sockname .family , 0 );
1394- if (dcc [j ].sock >= 0 ) {
1395- sockname_t name ;
1396- name .addrlen = sizeof (name .addr );
1397- if (getsockname (dcc [i ].sock , & name .addr .sa , & name .addrlen ) < 0 )
1398- debug2 ("dcc: dcc_telnet_hostresolved(): getsockname() socket %ld error %s" , dcc [i ].sock , strerror (errno ));
1399- setsnport (name , 0 );
1400- if (bind (dcc [j ].sock , & name .addr .sa , name .addrlen ) < 0 )
1401- debug2 ("dcc: dcc_telnet_hostresolved(): bind() socket %ld error %s" , dcc [j ].sock , strerror (errno ));
1402- setsnport (dcc [j ].sockname , 113 );
1403- if (connect (dcc [j ].sock , & dcc [j ].sockname .addr .sa ,
1404- dcc [j ].sockname .addrlen ) < 0 && (errno != EINPROGRESS )) {
1405- killsock (dcc [j ].sock );
1406- lostdcc (j );
1407- putlog (LOG_MISC , "*" , DCC_IDENTFAIL , dcc [i ].host , strerror (errno ));
1408- j = 0 ;
1409- }
1410- sock = dcc [j ].sock ;
1411- }
1412- }
1413- if (j < 0 ) {
1414- dcc_telnet_got_ident (i , userhost );
1415- return ;
1416- }
1417- dcc [j ].sock = sock ;
1418- dcc [j ].port = 113 ;
1419- dcc [j ].addr = dcc [i ].addr ;
1420- strcpy (dcc [j ].host , dcc [i ].host );
1421- strcpy (dcc [j ].nick , "*" );
1422- dcc [j ].u .ident_sock = dcc [i ].sock ;
1423- dcc [j ].timeval = now ;
1424- dprintf (j , "%d, %d\n" , dcc [i ].port , dcc [idx ].port );
1450+ strlcpy (dcc [i ].host , userhost , UHOSTLEN );
1451+ dcc_telnet_hostresolved2 (i , idx );
14251452}
14261453
14271454static void eof_dcc_telnet (int idx )
@@ -1551,7 +1578,6 @@ static void dcc_telnet_id(int idx, char *buf, int atr)
15511578 int ok = 0 ;
15521579 struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH , 0 , 0 , 0 , 0 , 0 };
15531580 struct dcc_table * old = dcc [idx ].type ;
1554-
15551581 if (detect_telnet ((unsigned char * ) buf )) {
15561582 dcc [idx ].status |= STAT_TELNET ;
15571583 strip_telnet (dcc [idx ].sock , buf , & atr );
@@ -1808,14 +1834,20 @@ static void dcc_telnet_pass(int idx, int atr)
18081834 * <Cybah>
18091835 */
18101836
1811- /* Turn off remote telnet echo (send IAC WILL ECHO). */
1837+ /* Turn off remote telnet echo */
1838+ char buf [512 ];
18121839 if (dcc [idx ].status & STAT_TELNET ) {
1813- char buf [ 1030 ];
1840+ /* For telnet sessions send IAC WILL ECHO */
18141841 egg_snprintf (buf , sizeof buf , "\n%s%s\r\n" , escape_telnet (DCC_ENTERPASS ),
18151842 TLN_IAC_C TLN_WILL_C TLN_ECHO_C );
18161843 tputs (dcc [idx ].sock , buf , strlen (buf ));
1817- } else
1844+ } else if (dcc [idx ].status & STAT_WS ) {
1845+ /* For webui sessions */
1846+ snprintf (buf , sizeof buf , "\n%s" WS_ECHO_OFF "\n" , DCC_ENTERPASS );
1847+ tputs (dcc [idx ].sock , buf , strlen (buf ));
1848+ } else {
18181849 dprintf (idx , "\n%s\n" , DCC_ENTERPASS );
1850+ }
18191851 }
18201852}
18211853
@@ -2387,7 +2419,6 @@ static void dcc_telnet_got_ident(int i, char *host)
23872419 /* Do not buffer data anymore. All received and stored data is passed
23882420 * over to the dcc functions from now on. */
23892421 sockoptions (dcc [i ].sock , EGG_OPTION_UNSET , SOCK_BUFFER );
2390-
23912422 dcc [i ].type = & DCC_TELNET_ID ;
23922423 dcc [i ].u .chat = get_data_ptr (sizeof (struct chat_info ));
23932424 egg_bzero (dcc [i ].u .chat , sizeof (struct chat_info ));
@@ -2396,17 +2427,20 @@ static void dcc_telnet_got_ident(int i, char *host)
23962427 * STATUS option as a hopefully harmless way to detect if the other
23972428 * side is a telnet client or not. */
23982429#ifdef TLS
2399- if (!dcc [i ].ssl )
2400- dprintf (i , TLN_IAC_C TLN_WILL_C TLN_STATUS_C );
2430+ if (!dcc [i ].ssl && strcmp ( dcc [ idx ]. nick , "(webui)" ) )
2431+ dprintf (i , TLN_IAC_C TLN_WILL_C TLN_STATUS_C );
24012432#endif
2402- /* Copy acceptable-nick/host mask */
2403- dcc [i ].status = STAT_TELNET | STAT_ECHO ;
2404- if (!strcmp (dcc [idx ].nick , "(bots)" ))
2405- dcc [i ].status |= STAT_BOTONLY ;
2406- if (!strcmp (dcc [idx ].nick , "(users)" ))
2407- dcc [i ].status |= STAT_USRONLY ;
2408- /* Copy acceptable-nick/host mask */
2409- strlcpy (dcc [i ].nick , dcc [idx ].host , HANDLEN );
2433+ /* Copy acceptable-nick/host mask */
2434+ dcc [i ].status = STAT_TELNET | STAT_ECHO ;
2435+ if (!strcmp (dcc [idx ].nick , "(users)" ))
2436+ dcc [i ].status |= STAT_USRONLY ;
2437+ else if (!strcmp (dcc [idx ].nick , "(bots)" ))
2438+ dcc [i ].status |= STAT_BOTONLY ;
2439+ else if (!strcmp (dcc [idx ].nick , "(webui)" ))
2440+ dcc [i ].status |= STAT_WS ;
2441+ /* Copy acceptable-nick/host mask */
2442+ strlcpy (dcc [i ].nick , dcc [idx ].host , HANDLEN ); /* wo ist hier der sinn? dcc[idx].host ist immer *, oder? */
2443+
24102444 dcc [i ].timeval = now ;
24112445 strcpy (dcc [i ].u .chat -> con_chan , chanset ? chanset -> dname : "*" );
24122446 /* Displays a customizable banner. */
0 commit comments