Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(RFC) WebUI mod #1467

Open
wants to merge 29 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
930c847
Initial commit
michaelortmann Feb 7, 2023
12da7cb
Merge remote-tracking branch 'upstream/develop' into webui.mod
Oct 8, 2023
cd7b272
Merge remote-tracking branch 'upstream/develop' into webui.mod
Dec 3, 2023
7ce5a98
Merge remote-tracking branch 'upstream/develop' into webui.mod
Jan 15, 2024
877f119
Merge remote-tracking branch 'upstream/develop' into webui.mod
May 6, 2024
0524163
Enhance log
May 6, 2024
3758fca
Remove debug log
May 6, 2024
54e10f7
Update Copyright
May 7, 2024
063fc5c
Renamed webui.html -> text/webui.html
May 7, 2024
e23e9f2
add character encoding
May 7, 2024
356c5cc
Remove trailing slash on void element
May 7, 2024
8317e39
Use CSS instead of obsolete elements
May 7, 2024
a61d236
Add lang attribute
May 7, 2024
a2c4224
Fix for sock == -1 if lostdcc() in dcc_telnet_hostresolved2()
May 27, 2024
69fd33a
Merge remote-tracking branch 'upstream/develop' into webui.mod
May 27, 2024
cc6ff81
Merge remote-tracking branch 'upstream/develop' into webui.mod
michaelortmann Jul 6, 2024
17c5636
Merge remote-tracking branch 'upstream/develop' into webui.mod
michaelortmann Jul 10, 2024
9e232d2
Merge remote-tracking branch 'upstream/develop' into webui.mod
michaelortmann Jul 10, 2024
056c153
Fix proto.h / --disable-tls
michaelortmann Jul 10, 2024
8dca49f
Enhance TODO doc
michaelortmann Jul 11, 2024
ebeeebb
Fix --disable-tls
michaelortmann Jul 11, 2024
f7f2417
Fix openssl 0.9.8 even for WIP/testing
michaelortmann Aug 1, 2024
fd12695
Merge remote-tracking branch 'upstream/develop' into webui.mod
michaelortmann Aug 1, 2024
9e3bef5
Fix openssl version < 1.1
michaelortmann Aug 1, 2024
03cf0f7
misc/makedepend
michaelortmann Aug 1, 2024
874f44e
Added experimental http feedback, if user connects http to https port
michaelortmann Aug 1, 2024
bad09ce
misc/makedepend
michaelortmann Aug 1, 2024
6d9502e
Fix format specifier
michaelortmann Aug 1, 2024
f8fde3f
Remove forgotten debug
michaelortmann Aug 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eggdrop-basic.conf
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ loadmodule console ; # Console setting storage
loadmodule uptime ; # Centralized uptime stat collection (https://www.eggheads.org/uptime/)
#loadmodule ident ; # Ident support
#loadmodule twitch ; # Twitch gaming service support
#loadmodule webui ; # WebUI support


##### BASIC SETTINGS #####
Expand Down
7 changes: 7 additions & 0 deletions eggdrop.conf
Original file line number Diff line number Diff line change
Expand Up @@ -1664,6 +1664,13 @@ loadmodule uptime
# Set the ident port to use for ident-method 1.
#set ident-port 113


#### WEBUI MODULE ####

#loadmodule webui

#listen +8080 webui

##### AUTOSCRIPTS #####

# Load this script to enable the autoscripts functionality for Eggdrop.
Expand Down
3 changes: 2 additions & 1 deletion src/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ tcluser.o: tcluser.c main.h ../config.h ../eggint.h ../lush.h lang.h \
tls.o: tls.c main.h ../config.h ../eggint.h ../lush.h lang.h eggdrop.h \
compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h tclhash.h \
chan.h users.h compat/compat.h compat/base64.h compat/inet_aton.h \
../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h
../src/main.h compat/snprintf.h compat/explicit_bzero.h compat/strlcpy.h \
version.h
userent.o: userent.c main.h ../config.h ../eggint.h ../lush.h lang.h \
eggdrop.h compat/in6.h flags.h proto.h misc_file.h cmdt.h tclegg.h \
tclhash.h chan.h users.h compat/compat.h compat/base64.h \
Expand Down
172 changes: 103 additions & 69 deletions src/dcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,8 @@ static void dcc_chat_pass(int idx, char *buf, int atr)
/* Turn echo back on for telnet sessions (send IAC WON'T ECHO). */
if (dcc[idx].status & STAT_TELNET)
tputs(dcc[idx].sock, TLN_IAC_C TLN_WONT_C TLN_ECHO_C "\n", 4);
else if (dcc[idx].status & STAT_WS)
tputs(dcc[idx].sock, WS_ECHO_ON, 1);
dcc_chatter(idx);
}
} else {
Expand Down Expand Up @@ -1296,11 +1298,18 @@ static void dcc_telnet(int idx, char *buf, int i)
*/
if (!(tls_vfyclients & TLS_VERIFYCN))
threaddata()->socklist[findsock(sock)].flags |= SOCK_VIRTUAL;
else if (ssl_handshake(dcc[i].sock, TLS_LISTEN, tls_vfyclients,
LOG_MISC, NULL, NULL)) {
killsock(dcc[i].sock);
lostdcc(i);
return;
else {
#ifdef TLS
if (!strcmp(dcc[idx].nick, "(webui)"))
ssl_cleanup(); /* reset ssl_ctx for websocket */
#endif /* TLS */
if (ssl_handshake(dcc[i].sock, TLS_LISTEN,
strcmp(dcc[idx].nick, "(webui)") ? tls_vfyclients : 0,
LOG_MISC, NULL, NULL)) {
killsock(dcc[i].sock);
lostdcc(i);
return;
}
}
}
#endif
Expand All @@ -1314,12 +1323,71 @@ static void dcc_telnet(int idx, char *buf, int i)
dcc_dnshostbyip(&dcc[i].sockname);
}

/* we need this for dcc_telnet_hostresolved() could now branch to DCC_TABLE
* and for either branch we need to continue here
*/
void dcc_telnet_hostresolved2(int i, int idx) {
int j, sock;
char *userhost = dcc[idx].host; /* TODO: writing host back to userhost looks like back and forth copying */
/* Skip ident lookup if disabled */
if (identtimeout <= 0) {
dcc[i].u.ident_sock = dcc[idx].sock;
dcc_telnet_got_ident(i, userhost);
return;
}

changeover_dcc(i, &DCC_IDENTWAIT, 0);
dcc[i].timeval = now;
dcc[i].u.ident_sock = dcc[idx].sock;
sock = -1;
j = new_dcc(&DCC_IDENT, 0);
if (j < 0)
putlog(LOG_MISC, "*", DCC_IDENTFAIL, dcc[i].host, strerror(errno));
else {
memcpy(&dcc[j].sockname, &dcc[i].sockname, sizeof(sockname_t));
dcc[j].sock = getsock(dcc[j].sockname.family, 0);
if (dcc[j].sock >= 0) {
sockname_t name;
name.addrlen = sizeof(name.addr);
if (getsockname(dcc[i].sock, &name.addr.sa, &name.addrlen) < 0)
debug2("dcc: dcc_telnet_hostresolved(): getsockname() socket %ld error %s", dcc[i].sock, strerror(errno));
setsnport(name, 0);
if (bind(dcc[j].sock, &name.addr.sa, name.addrlen) < 0)
debug2("dcc: dcc_telnet_hostresolved(): bind() socket %ld error %s", dcc[j].sock, strerror(errno));
setsnport(dcc[j].sockname, 113);
if (connect(dcc[j].sock, &dcc[j].sockname.addr.sa,
dcc[j].sockname.addrlen) < 0 && (errno != EINPROGRESS)) {
killsock(dcc[j].sock);
lostdcc(j);
putlog(LOG_MISC, "*", DCC_IDENTFAIL, dcc[i].host, strerror(errno));
j = 0;
}
sock = dcc[j].sock;
}
}
if (j < 0) {
dcc_telnet_got_ident(i, userhost);
return;
}
dcc[j].sock = sock;
dcc[j].port = 113;
dcc[j].addr = dcc[i].addr;
strcpy(dcc[j].host, dcc[i].host);
strcpy(dcc[j].nick, "*");
dcc[j].u.ident_sock = dcc[i].sock;
dcc[j].timeval = now;
#ifdef CYGWIN_HACKS
threaddata()->socklist[findsock(dcc[j].sock)].flags = SOCK_CONNECT;
#endif
dprintf(j, "%d, %d\n", dcc[i].port, dcc[idx].port);
}

static void dcc_telnet_hostresolved(int i)
{
int idx;
int j = 0, sock;
char s[sizeof lasttelnethost], *userhost;

debug0("dcc_telnet_hostresolved()");
strlcpy(dcc[i].host, dcc[i].u.dns->host, UHOSTLEN);

for (idx = 0; idx < dcc_total; idx++)
Expand Down Expand Up @@ -1378,57 +1446,16 @@ static void dcc_telnet_hostresolved(int i)
return;
}

/* Skip ident lookup if disabled */
if (identtimeout <= 0) {
dcc[i].u.ident_sock = dcc[idx].sock;
dcc_telnet_got_ident(i, userhost);
#ifdef TLS
/* Skip ident lookup for webui http */
if (!strcmp(dcc[idx].nick, "(webui)")) {
webui_dcc_telnet_hostresolved(i);
return;
}
#endif /* TLS */

changeover_dcc(i, &DCC_IDENTWAIT, 0);
dcc[i].timeval = now;
dcc[i].u.ident_sock = dcc[idx].sock;
sock = -1;
j = new_dcc(&DCC_IDENT, 0);
if (j < 0)
putlog(LOG_MISC, "*", DCC_IDENTFAIL, dcc[i].host, strerror(errno));
else {
memcpy(&dcc[j].sockname, &dcc[i].sockname, sizeof(sockname_t));
dcc[j].sock = getsock(dcc[j].sockname.family, 0);
if (dcc[j].sock >= 0) {
sockname_t name;
name.addrlen = sizeof(name.addr);
if (getsockname(dcc[i].sock, &name.addr.sa, &name.addrlen) < 0)
debug2("dcc: dcc_telnet_hostresolved(): getsockname() socket %ld error %s", dcc[i].sock, strerror(errno));
setsnport(name, 0);
if (bind(dcc[j].sock, &name.addr.sa, name.addrlen) < 0)
debug2("dcc: dcc_telnet_hostresolved(): bind() socket %ld error %s", dcc[j].sock, strerror(errno));
setsnport(dcc[j].sockname, 113);
if (connect(dcc[j].sock, &dcc[j].sockname.addr.sa,
dcc[j].sockname.addrlen) < 0 && (errno != EINPROGRESS)) {
killsock(dcc[j].sock);
lostdcc(j);
putlog(LOG_MISC, "*", DCC_IDENTFAIL, dcc[i].host, strerror(errno));
j = 0;
}
sock = dcc[j].sock;
}
}
if (j < 0) {
dcc_telnet_got_ident(i, userhost);
return;
}
dcc[j].sock = sock;
dcc[j].port = 113;
dcc[j].addr = dcc[i].addr;
strcpy(dcc[j].host, dcc[i].host);
strcpy(dcc[j].nick, "*");
dcc[j].u.ident_sock = dcc[i].sock;
dcc[j].timeval = now;
#ifdef CYGWIN_HACKS
threaddata()->socklist[findsock(dcc[j].sock)].flags = SOCK_CONNECT;
#endif
dprintf(j, "%d, %d\n", dcc[i].port, dcc[idx].port);
strlcpy(dcc[i].host, userhost, UHOSTLEN);
dcc_telnet_hostresolved2(i, idx);
}

static void eof_dcc_telnet(int idx)
Expand Down Expand Up @@ -1558,7 +1585,6 @@ static void dcc_telnet_id(int idx, char *buf, int atr)
int ok = 0;
struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
struct dcc_table *old = dcc[idx].type;

if (detect_telnet((unsigned char *) buf)) {
dcc[idx].status |= STAT_TELNET;
strip_telnet(dcc[idx].sock, buf, &atr);
Expand Down Expand Up @@ -1824,14 +1850,20 @@ static void dcc_telnet_pass(int idx, int atr)
* <Cybah>
*/

/* Turn off remote telnet echo (send IAC WILL ECHO). */
/* Turn off remote telnet echo */
char buf[512];
if (dcc[idx].status & STAT_TELNET) {
char buf[1030];
/* For telnet sessions send IAC WILL ECHO */
egg_snprintf(buf, sizeof buf, "\n%s%s\r\n", escape_telnet(DCC_ENTERPASS),
TLN_IAC_C TLN_WILL_C TLN_ECHO_C);
tputs(dcc[idx].sock, buf, strlen(buf));
} else
} else if (dcc[idx].status & STAT_WS) {
/* For webui sessions */
snprintf(buf, sizeof buf, "\n%s" WS_ECHO_OFF "\n", DCC_ENTERPASS);
tputs(dcc[idx].sock, buf, strlen(buf));
} else {
dprintf(idx, "\n%s\n", DCC_ENTERPASS);
}
}
}

Expand Down Expand Up @@ -2403,7 +2435,6 @@ static void dcc_telnet_got_ident(int i, char *host)
/* Do not buffer data anymore. All received and stored data is passed
* over to the dcc functions from now on. */
sockoptions(dcc[i].sock, EGG_OPTION_UNSET, SOCK_BUFFER);

dcc[i].type = &DCC_TELNET_ID;
dcc[i].u.chat = get_data_ptr(sizeof(struct chat_info));
egg_bzero(dcc[i].u.chat, sizeof(struct chat_info));
Expand All @@ -2412,17 +2443,20 @@ static void dcc_telnet_got_ident(int i, char *host)
* STATUS option as a hopefully harmless way to detect if the other
* side is a telnet client or not. */
#ifdef TLS
if (!dcc[i].ssl)
dprintf(i, TLN_IAC_C TLN_WILL_C TLN_STATUS_C);
if (!dcc[i].ssl && strcmp(dcc[idx].nick, "(webui)"))
dprintf(i, TLN_IAC_C TLN_WILL_C TLN_STATUS_C);
#endif
/* Copy acceptable-nick/host mask */
dcc[i].status = STAT_TELNET | STAT_ECHO;
if (!strcmp(dcc[idx].nick, "(bots)"))
dcc[i].status |= STAT_BOTONLY;
if (!strcmp(dcc[idx].nick, "(users)"))
dcc[i].status |= STAT_USRONLY;
/* Copy acceptable-nick/host mask */
strlcpy(dcc[i].nick, dcc[idx].host, HANDLEN);
/* Copy acceptable-nick/host mask */
dcc[i].status = STAT_TELNET | STAT_ECHO;
if (!strcmp(dcc[idx].nick, "(users)"))
dcc[i].status |= STAT_USRONLY;
else if (!strcmp(dcc[idx].nick, "(bots)"))
dcc[i].status |= STAT_BOTONLY;
else if (!strcmp(dcc[idx].nick, "(webui)"))
dcc[i].status |= STAT_WS;
/* Copy acceptable-nick/host mask */
strlcpy(dcc[i].nick, dcc[idx].host, HANDLEN); /* wo ist hier der sinn? dcc[idx].host ist immer *, oder? */

dcc[i].timeval = now;
strcpy(dcc[i].u.chat->con_chan, chanset ? chanset->dname : "*");
/* Displays a customizable banner. */
Expand Down
5 changes: 5 additions & 0 deletions src/eggdrop.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ struct dupwait_info {
#define STAT_USRONLY 0x00040 /* telnet on users-only connect */
#define STAT_PAGE 0x00080 /* page output to the user */
#define STAT_SERV 0x00100 /* this is a server connection */
#define STAT_WS 0x00200 /* webui websocket */

/* For stripping out mIRC codes. */
#define STRIP_COLOR 0x00001 /* remove mIRC color codes */
Expand Down Expand Up @@ -602,6 +603,7 @@ typedef struct {
#define SOCK_VIRTUAL 0x0200 /* not-connected socket (dont read it!) */
#define SOCK_BUFFER 0x0400 /* buffer data; don't notify dcc funcs */
#define SOCK_TCL 0x0800 /* tcl socket, don't do anything on it */
#define SOCK_WS 0x1000 /* webui websocket */

/* Flags to sock_has_data
*/
Expand Down Expand Up @@ -754,4 +756,7 @@ struct dns_thread_node {
extern struct dns_thread_node *dns_thread_head;
#endif

#define WS_ECHO_ON "\x01" /* echo on */
#define WS_ECHO_OFF "\x02" /* echo off */

#endif /* _EGG_EGGDROP_H */
4 changes: 0 additions & 4 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,6 @@ unsigned long itraffic_unknown_today = 0;
extern char last_bind_called[];
#endif

#ifdef TLS
int ssl_cleanup();
#endif

void fatal(const char *s, int recoverable)
{
int i;
Expand Down
2 changes: 2 additions & 0 deletions src/mod/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,8 @@ typedef void (*chanout_butfunc)(int, int, const char *, ...) ATTRIBUTE_FORMAT(pr
/* 324 - 327 */
#define find_member_from_nick ((memberlist * (*) (char *))global[324])
#define get_user_from_member ((struct userrec * (*) (memberlist *))global[325])
#define dcc_telnet_hostresolved2 ((void(*)(int, int))global[326])
#define findsock ((int(*)(int))global[327])


/* hostmasking */
Expand Down
67 changes: 35 additions & 32 deletions src/mod/modvals.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,40 +23,43 @@
#ifndef _EGG_MOD_MODVALS_H
#define _EGG_MOD_MODVALS_H

/* #define HOOK_GET_FLAGREC 0 */
/* #define HOOK_BUILD_FLAGREC 1 */
/* #define HOOK_SET_FLAGREC 2 */
#define HOOK_READ_USERFILE 3
#define HOOK_REHASH 4
#define HOOK_MINUTELY 5
#define HOOK_DAILY 6
#define HOOK_HOURLY 7
#define HOOK_USERFILE 8
#define HOOK_SECONDLY 9
#define HOOK_PRE_REHASH 10
#define HOOK_IDLE 11
#define HOOK_5MINUTELY 12
#define HOOK_LOADED 13
#define HOOK_BACKUP 14
#define HOOK_DIE 15
#define HOOK_PRE_SELECT 16
#define HOOK_POST_SELECT 17
/* #define HOOK_GET_FLAGREC 0 */
/* #define HOOK_BUILD_FLAGREC 1 */
/* #define HOOK_SET_FLAGREC 2 */
#define HOOK_READ_USERFILE 3
#define HOOK_REHASH 4
#define HOOK_MINUTELY 5
#define HOOK_DAILY 6
#define HOOK_HOURLY 7
#define HOOK_USERFILE 8
#define HOOK_SECONDLY 9
#define HOOK_PRE_REHASH 10
#define HOOK_IDLE 11
#define HOOK_5MINUTELY 12
#define HOOK_LOADED 13
#define HOOK_BACKUP 14
#define HOOK_DIE 15
#define HOOK_PRE_SELECT 16
#define HOOK_POST_SELECT 17

#define REAL_HOOKS 18
#define REAL_HOOKS 18

#define HOOK_SHAREOUT 105
#define HOOK_SHAREIN 106
#define HOOK_ENCRYPT_PASS 107
#define HOOK_QSERV 108
#define HOOK_ADD_MODE 109
#define HOOK_MATCH_NOTEREJ 110
#define HOOK_RFC_CASECMP 111
#define HOOK_DNS_HOSTBYIP 112
#define HOOK_DNS_IPBYHOST 113
#define HOOK_ENCRYPT_STRING 114
#define HOOK_DECRYPT_STRING 115
#define HOOK_ENCRYPT_PASS2 116
#define HOOK_VERIFY_PASS2 117
#define HOOK_SHAREOUT 105
#define HOOK_SHAREIN 106
#define HOOK_ENCRYPT_PASS 107
#define HOOK_QSERV 108
#define HOOK_ADD_MODE 109
#define HOOK_MATCH_NOTEREJ 110
#define HOOK_RFC_CASECMP 111
#define HOOK_DNS_HOSTBYIP 112
#define HOOK_DNS_IPBYHOST 113
#define HOOK_ENCRYPT_STRING 114
#define HOOK_DECRYPT_STRING 115
#define HOOK_ENCRYPT_PASS2 116
#define HOOK_VERIFY_PASS2 117
#define HOOK_DCC_TELNET_HOSTRESOLVED 118
#define HOOK_WEBUI_FRAME 119
#define HOOK_WEBUI_UNFRAME 120

/* These are FIXED once they are in a release they STAY */
#define MODCALL_START 0
Expand Down
Loading