Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelortmann authored and Michael Ortmann committed Aug 31, 2023
1 parent 81b5f6a commit 930c847
Show file tree
Hide file tree
Showing 16 changed files with 897 additions and 150 deletions.
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 (http://uptime.eggheads.org)
#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 @@ -1680,6 +1680,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
166 changes: 100 additions & 66 deletions src/dcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,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 @@ -1292,11 +1294,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 @@ -1310,12 +1319,68 @@ 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;
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 @@ -1374,54 +1439,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;
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 @@ -1551,7 +1578,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 @@ -1808,14 +1834,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 @@ -2387,7 +2419,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 @@ -2396,17 +2427,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 @@ -543,6 +543,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 @@ -654,6 +655,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 @@ -805,4 +807,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 @@ -178,10 +178,6 @@ int cx_line[16];
int cx_ptr = 0;
#endif

#ifdef TLS
int ssl_cleanup();
#endif

void fatal(const char *s, int recoverable)
{
int i;
Expand Down
3 changes: 3 additions & 0 deletions src/mod/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,9 @@ typedef void (*chanout_butfunc)(int, int, const char *, ...) ATTRIBUTE_FORMAT(pr
#define USERENTRY_ACCOUNT (*(struct user_entry_type *)(global[316]))
#define get_user_by_account ((struct userrec * (*)(char *))global[317])
#define delaccount_by_handle ((int(*)(char *,char *))global[318])
#define dcc_telnet_hostresolved2 ((void(*)(int, int))global[319])
/* 320 - 323 */
#define findsock ((int(*)(int))global[320])



Expand Down
63 changes: 33 additions & 30 deletions src/mod/modvals.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,39 @@
#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 REAL_HOOKS 16
#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_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 REAL_HOOKS 16
#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

0 comments on commit 930c847

Please sign in to comment.