Skip to content

Instantly share code, notes, and snippets.

@typhonius
Created April 18, 2013 04:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save typhonius/5410170 to your computer and use it in GitHub Desktop.
Save typhonius/5410170 to your computer and use it in GitHub Desktop.
patch for odch to allow users to be muted
diff --git a/src/commands.c b/src/commands.c
index 411f944..7af604f 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -480,6 +480,23 @@ void chat(char *buf, struct user_t *user)
logprintf(3, "OP Admin %s at %s added %s to nickban list\n", user->nick, user->hostname, tempstr);
}
}
+
+ else if(((user->permissions & BAN_ALLOW) != 0) && (strncasecmp(temp, "!gag ", 5) == 0))
+ {
+ if((ret = ballow(temp+5, GAG, user)) == -1)
+ {
+ uprintf(user, "<Hub-Security> Couldn't add entry to gag list|");
+ logprintf(4, "Error - Failed adding entry to gag list\n");
+ }
+ else if(ret == 2)
+ uprintf(user, "<Hub-Security> Entry is already on the list|");
+ else
+ {
+ uprintf(user, "<Hub-Security> Added entry to gag list|");
+ sscanf(temp+5, "%120[^|]", tempstr);
+ logprintf(3, "OP Admin %s at %s added %s to gag list\n", user->nick, user->hostname, tempstr);
+ }
+ }
else if(((user->permissions & BAN_ALLOW) != 0) && (strncasecmp(temp, "!allow ", 7) == 0))
{
@@ -529,6 +546,23 @@ void chat(char *buf, struct user_t *user)
logprintf(3, "OP Admin %s at %s removed %s from nickban list\n", user->nick, user->hostname, tempstr);
}
}
+
+ else if(((user->permissions & BAN_ALLOW) != 0) && (strncasecmp(temp, "!ungag ", 7) == 0))
+ {
+ if((ret = unballow(temp+7, GAG)) == -1)
+ {
+ uprintf(user, "<Hub-Security> Couldn't remove entry from gag list|");
+ logprintf(4, "Error - Failed removing entry from gag list\n");
+ }
+ else if(ret == 0)
+ uprintf(user, "<Hub-Security> Entry wasn't found in list|");
+ else
+ {
+ uprintf(user, "<Hub-Security> Removed entry from gag list|");
+ sscanf(temp+7, "%120[^|]", tempstr);
+ logprintf(3, "OP Admin %s at %s removed %s from gag list\n", user->nick, user->hostname, tempstr);
+ }
+ }
else if(((user->permissions & BAN_ALLOW) != 0) && (strncasecmp(temp, "!unallow ", 9) == 0))
{
if((ret = unballow(temp+9, ALLOW)) == -1)
@@ -557,6 +591,12 @@ void chat(char *buf, struct user_t *user)
send_user_list(NICKBAN, user);
send_to_user("|", user);
}
+ else if(((user->permissions & BAN_ALLOW) != 0) && (strncasecmp(temp, "!getgaglist", 11) == 0))
+ {
+ uprintf(user, "<Hub-Security> Gag list:\r\n");
+ send_user_list(GAG, user);
+ send_to_user("|", user);
+ }
else if(((user->permissions & BAN_ALLOW) != 0) && (strncasecmp(temp, "!getallowlist", 13) == 0))
{
uprintf(user, "<Hub-Security> Allow list:\r\n");
@@ -727,8 +767,15 @@ void chat(char *buf, struct user_t *user)
else
{
/* And forward the message to all. */
+ /* Check if user is gagged first */
+ if (user->gag == 1)
+ {
+ uprintf(user, "<Hub-Security> You are gagged. No talking for you.|");
+ }
+ else {
send_to_non_humans(buf, FORKED, user);
send_to_humans(buf, REGULAR | REGISTERED | OP | OP_ADMIN, NULL);
+ }
}
}
@@ -2421,6 +2468,7 @@ int ballow(char *buf, int type, struct user_t *user)
time_t ban_time = 0;
time_t old_time;
time_t now_time;
+ struct user_t *targ_user;
/* ban_user[0] = '\0'; */
@@ -2430,11 +2478,13 @@ int ballow(char *buf, int type, struct user_t *user)
snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, ALLOW_FILE);
else if(type == NICKBAN)
snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, NICKBAN_FILE);
+ else if(type == GAG)
+ snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, GAG_FILE);
else
return -1;
now_time = time(NULL);
- if(type == NICKBAN)
+ if(type == NICKBAN || GAG)
{
if(sscanf(buf, "%50s %lu%c", ban_host, &ban_time, &period) == 1)
ban_host[strlen(ban_host) - 1] = '\0';
@@ -2561,8 +2611,15 @@ int ballow(char *buf, int type, struct user_t *user)
return -1;
}
- if(type == NICKBAN)
+ if(type == NICKBAN || GAG)
{
+ if(type == GAG)
+ {
+ if((targ_user = get_human_user(ban_host)) != NULL)
+ {
+ targ_user->gag = 1;
+ }
+ }
if (ban_time > 0)
sprintf(ban_line, "%s %lu", ban_host, now_time + ban_time);
else
@@ -2627,6 +2684,21 @@ int ballow(char *buf, int type, struct user_t *user)
non_format_to_scripts(ban_host);
}
command_to_scripts("|");
+ }
+ else if(type == GAG)
+ {
+ if (ban_time > 0)
+ {
+ command_to_scripts("$Script added_temp_gag %c%c", '\005', '\005');
+ non_format_to_scripts(ban_host);
+ command_to_scripts("%c%c%lu", '\005', '\005', ban_time);
+ }
+ else
+ {
+ command_to_scripts("$Script added_perm_gag %c%c", '\005', '\005');
+ non_format_to_scripts(ban_host);
+ }
+ command_to_scripts("|");
}
}
#endif
@@ -2641,6 +2713,7 @@ int unballow(char *buf, int type)
int ret;
char line[MAX_HOST_LEN+1];
char path[MAX_FDP_LEN+1];
+ struct user_t *targ_user;
if(type == BAN)
snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, BAN_FILE);
@@ -2648,11 +2721,20 @@ int unballow(char *buf, int type)
snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, ALLOW_FILE);
else if(type == NICKBAN)
snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, NICKBAN_FILE);
+ else if(type == GAG)
+ snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, GAG_FILE);
else
return -1;
sscanf(buf, "%120[^|]", line);
remove_exp_from_file(time(NULL), path);
+ if(type == GAG)
+ {
+ if((targ_user = get_human_user(line)) != NULL)
+ {
+ targ_user->gag = 0;
+ }
+ }
ret = remove_line_from_file(line, path, 0);
return ret;
@@ -2682,6 +2764,8 @@ void send_user_list(int type, struct user_t *user)
snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, LINK_FILE);
else if(type == NICKBAN)
snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, NICKBAN_FILE);
+ else if(type == GAG)
+ snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, GAG_FILE);
else
return;
@@ -3105,6 +3189,13 @@ void send_commands(struct user_t *user)
uprintf(user, "Adds an entry to the nick banlist. The time is the same as for the ban command\r\n\r\n");
if(user->type == ADMIN)
+ uprintf(user, "$gag 'nick' 'time'|\r\n");
+ else if(((user->permissions & BAN_ALLOW) != 0) && ((user->type & (OP_ADMIN | OP)) != 0))
+ uprintf(user, "!gag 'nick' 'time'\r\n");
+ if(((user->type & (ADMIN | OP_ADMIN)) != 0) || ((user->permissions & BAN_ALLOW) != 0))
+ uprintf(user, "Adds an entry to the gaglist. The time is the same as for the ban command\r\n\r\n");
+
+ if(user->type == ADMIN)
uprintf(user, "$allow 'ip or hostname'|\r\n");
else if(((user->permissions & BAN_ALLOW) != 0) && ((user->type & (OP_ADMIN | OP)) != 0))
uprintf(user, "!allow 'ip or hostname'\r\n");
@@ -3124,6 +3215,13 @@ void send_commands(struct user_t *user)
uprintf(user, "!getnickbanlist\r\n");
if(((user->type & (ADMIN | OP_ADMIN)) != 0) || ((user->permissions & BAN_ALLOW) != 0))
uprintf(user, "Displays the nick banlist file.\r\n\r\n");
+
+ if(user->type == ADMIN)
+ uprintf(user, "$getgaglist|\r\n");
+ else if(((user->permissions & BAN_ALLOW) != 0) && ((user->type & (OP_ADMIN | OP)) != 0))
+ uprintf(user, "!getgaglist\r\n");
+ if(((user->type & (ADMIN | OP_ADMIN)) != 0) || ((user->permissions & BAN_ALLOW) != 0))
+ uprintf(user, "Displays the gaglist file.\r\n\r\n");
if(user->type == ADMIN)
uprintf(user, "$getallowlist|\r\n");
@@ -3147,6 +3245,13 @@ void send_commands(struct user_t *user)
uprintf(user, "Removes an entry from the nick banlist file. The nick entry in the file must\r\nbe an exact match of the one provided in the command.\r\n\r\n");
if(user->type == ADMIN)
+ uprintf(user, "$ungag 'nick'|\r\n");
+ else if(((user->permissions & BAN_ALLOW) != 0) && ((user->type & (OP_ADMIN | OP)) != 0 ))
+ uprintf(user, "!ungag 'nick'\r\n");
+ if(((user->type & (ADMIN | OP_ADMIN)) != 0) || ((user->permissions & BAN_ALLOW) != 0))
+ uprintf(user, "Removes an entry from the gaglist file. The nick entry in the file must\r\nbe an exact match of the one provided in the command.\r\n\r\n");
+
+ if(user->type == ADMIN)
uprintf(user, "$unallow 'ip or hostname'|\r\n");
else if(((user->permissions & BAN_ALLOW) != 0) && ((user->type & (OP_ADMIN | OP)) != 0))
uprintf(user, "!unallow 'ip or hostname'\r\n");
@@ -3376,6 +3481,18 @@ void remove_expired(void)
remove_exp_from_file(now_time, path);
snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, NICKBAN_FILE);
remove_exp_from_file(now_time, path);
+ snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, GAG_FILE);
+ remove_exp_from_file(now_time, path);
+}
+
+int gag_user(char *buf, struct user_t *user)
+{
+
+}
+
+int ungag_user(char *buf, struct user_t *user)
+{
+
}
int show_perms(struct user_t *user, char *buf)
diff --git a/src/fileio.c b/src/fileio.c
index 0e64303..cbce391 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -627,6 +627,66 @@ void create_banlist(void)
}
}
+/* Creates gaglist if it does not exist */
+void create_gaglist(void)
+{
+ FILE *fp;
+ int fd;
+ int erret;
+ char path[MAX_FDP_LEN+1];
+
+ snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, GAG_FILE);
+
+ while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
+ logprintf(1, "Error - In create_gaglist()/open(): Interrupted system call. Trying again.\n");
+
+ if(fd >= 0)
+ {
+ /* gaglist already exists */
+ close(fd);
+ return;
+ }
+
+ while(((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) && (errno == EINTR))
+ logprintf(1, "Error - In create_gaglist()/open(): Interrupted system call. Trying again.\n");
+
+ if(fd < 0)
+ {
+ logprintf(1, "Error - In create_gaglist()/open(): ");
+ logerror(1, errno);
+ return;
+ }
+
+ /* Set the lock */
+ if(set_lock(fd, F_WRLCK) == 0)
+ {
+ logprintf(1, "Error - In create_gaglist(): Couldn't set lock\n");
+ close(fd);
+ return;
+ }
+
+ if((fp = fdopen(fd, "a")) == NULL)
+ {
+ logprintf(1, "Error - In create_gaglist()/fdopen(): ");
+ logerror(1, errno);
+ set_lock(fd, F_UNLCK);
+ close(fd);
+ return;
+ }
+
+ logprintf(1, "Created gaglist\n");
+ set_lock(fd, F_UNLCK);
+
+ while(((erret = fclose(fp)) != 0) && (errno == EINTR))
+ logprintf(1, "Error - In create_gaglist()/fclose(): Interrupted system call. Trying again.\n");
+
+ if(erret != 0)
+ {
+ logprintf(1, "Error - In create_gaglist()/fclose(): ");
+ logerror(1, errno);
+ }
+}
+
/* Creates nickbanlist if it does not exist */
void create_nickbanlist(void)
{
@@ -1286,6 +1346,103 @@ int check_if_allowed(struct user_t *user)
return 0;
}
+/* Returns 1 if a nick is on the gaglist */
+int check_if_gagged(struct user_t *user)
+{
+ int i, j;
+ int fd;
+ int erret;
+ FILE *fp;
+ char path[MAX_FDP_LEN+1];
+ char line[1024];
+ char gag_host[MAX_HOST_LEN+1];
+ char *string_ip = NULL;
+ unsigned long userip = 0;
+ unsigned long fileip = 0;
+ int byte1, byte2, byte3, byte4, mask;
+ time_t gag_time;
+ time_t now_time;
+
+ snprintf(path, MAX_FDP_LEN, "%s/%s", config_dir, GAG_FILE);
+
+ while(((fd = open(path, O_RDONLY)) < 0) && (errno == EINTR))
+ logprintf(1, "Error - In check_if_gagged()/open(): Interrupted system call. Trying again.\n");
+
+ if(fd < 0)
+ {
+ logprintf(1, "Error - In check_if_gagged()/open(): ");
+ logerror(1, errno);
+ return -1;
+ }
+
+ /* Set the lock */
+ if(set_lock(fd, F_RDLCK) == 0)
+ {
+ logprintf(1, "Error - In check_if_gagged(): Couldn't set file lock\n");
+ close(fd);
+ return -1;
+ }
+
+ if((fp = fdopen(fd, "r")) == NULL)
+ {
+ logprintf(1, "Error - In check_if_gagged()/fdopen(): ");
+ logerror(1, errno);
+ set_lock(fd, F_UNLCK);
+ close(fd);
+ return -1;
+ }
+
+ now_time = time(NULL);
+
+ while(fgets(line, 1023, fp) != NULL)
+ {
+ trim_string(line);
+ gag_time = 0;
+
+ j = strlen(line);
+ if(j != 0)
+ {
+ /* Jump to next char which isn't a space */
+ i = 0;
+ while(line[i] == ' ')
+ i++;
+
+ sscanf(line+i, "%120s %lu", gag_host, &gag_time);
+ /* Check if a nickname is gagged. */
+ if(((gag_time == 0) || (gag_time > now_time)))
+ {
+ set_lock(fd, F_UNLCK);
+ while(((erret = fclose(fp)) != 0) && (errno == EINTR))
+ logprintf(1, "Error - In check_if_gagged()/fclose(): Interrupted system call. Trying again.\n");
+
+ if(erret != 0)
+ {
+ logprintf(1, "Error - In check_if_gagged()/fclose(): ");
+ logerror(1, errno);
+ return -1;
+ }
+
+ return 1;
+ }
+
+ }
+ }
+ set_lock(fd, F_UNLCK);
+
+ while(((erret = fclose(fp)) != 0) && (errno == EINTR))
+ logprintf(1, "Error - In check_if_gagged()/fclose(): Interrupted system call. Trying again.\n");
+
+ if(erret != 0)
+ {
+ logprintf(1, "Error - In check_if_gagged()/fclose(): ");
+ logerror(1, errno);
+ return -1;
+ }
+
+ return 0;
+
+}
+
/* Returns 1 if a nick is on the registered list, 2 if nick is op and 3 if
* user is op_admin. */
int check_if_registered(char *user_nick)
diff --git a/src/fileio.h b/src/fileio.h
index c2cf790..f5c26ec 100644
--- a/src/fileio.h
+++ b/src/fileio.h
@@ -27,6 +27,7 @@ int get_permissions(char *user_nick);
int write_config_file(void);
int set_lock(int fd, int type);
void create_banlist(void);
+void create_gaglist(void);
void create_nickbanlist(void);
void create_allowlist(void);
void create_reglist(void);
diff --git a/src/main.c b/src/main.c
index 5dd7410..ea1f87e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1501,6 +1501,61 @@ int handle_command(char *buf, struct user_t *user)
uprintf(user, "\r\nUser is not an operator.\r\n");
}
}
+ else if(strncasecmp(temp, "$Gag ", 5) == 0)
+ {
+ if((user->type & (ADMIN | SCRIPT)) != 0)
+ {
+ ret = ballow(temp+5, GAG, user);
+ if(user->type == ADMIN)
+ {
+ if(ret == -1)
+ {
+ uprintf(user, "\r\nCouldn't add entry to gag list\r\n");
+ logprintf(4, "Error - Failed adding entry to gag list\n");
+ }
+ else if(ret == 2)
+ uprintf(user, "\r\nEntry is already on the list\r\n");
+ else
+ {
+ uprintf(user, "\r\nAdded entry to gag list\r\n");
+ sscanf(temp+9, "%120[^|]", tempstr);
+ logprintf(3, "Administrator at %s added %s to gag list\n", user->hostname, tempstr);
+ }
+ }
+ }
+ }
+ else if(strncasecmp(temp, "$GetGagList", 11) == 0)
+ {
+ if(user->type == ADMIN)
+ {
+ uprintf(user, "\r\nGag list:\r\n");
+ send_user_list(GAG, user);
+ uprintf(user, "\r\n");
+ }
+ }
+ else if(strncasecmp(temp, "$UnGag ", 7) == 0)
+ {
+ if((user->type & (ADMIN | SCRIPT)) != 0)
+ {
+ ret = unballow(temp+7, GAG);
+ if(user->type == ADMIN)
+ {
+ if(ret == -1)
+ {
+ uprintf(user, "\r\nCouldn't remove entry from nickban list\r\n");
+ logprintf(4, "Error - Failed adding entry to nickban list\n");
+ }
+ else if(ret == 2)
+ uprintf(user, "\r\nEntry wasn't found in list\r\n");
+ else
+ {
+ uprintf(user, "\r\nRemoved entry from nickban list\r\n");
+ sscanf(temp+9, "%120[^|]", tempstr);
+ logprintf(3, "Administrator at %s removed %s from nickban list\n", user->hostname, tempstr);
+ }
+ }
+ }
+ }
else if(strncasecmp(temp, "$NickBan ", 9) == 0)
{
if((user->type & (ADMIN | SCRIPT)) != 0)
@@ -1640,7 +1695,7 @@ int new_human_user(int sock)
int namelen;
int yes = 1;
int i = 0;
- int banret, allowret;
+ int banret, allowret, gagret;
int socknum;
int erret;
int flags;
@@ -1820,6 +1875,16 @@ int new_human_user(int sock)
return -1;
}
}
+ /* Check if the user is gagged */
+ gagret = check_if_gagged(user);
+ if (gagret == 1)
+ {
+ user->gag = 1;
+ }
+ else
+ {
+ user->gag = 0;
+ }
/* Add sock struct of the user. */
add_socket(user);
@@ -2701,6 +2766,7 @@ int main(int argc, char *argv[])
logprintf(1, "Created motd file\n");
create_banlist();
+ create_gaglist();
create_nickbanlist();
create_allowlist();
create_reglist();
diff --git a/src/main.h b/src/main.h
index 5b1e4c8..e8d75d7 100644
--- a/src/main.h
+++ b/src/main.h
@@ -41,6 +41,7 @@
#define CONFIG_FILE "config" /* Name of config file */
#define MOTD_FILE "motd" /* Name of file containing the motd */
+#define GAG_FILE "gaglist" /* Name of file with gagged users in */
#define BAN_FILE "banlist" /* Name of file with banlist */
#define NICKBAN_FILE "nickbanlist" /* Name of file with nick banlist */
#define ALLOW_FILE "allowlist" /* Name of file with allowlist */
@@ -92,6 +93,7 @@
#define CONFIG 3
#define LINK 4
#define NICKBAN 5
+#define GAG 6
#define HOST 0
#define IP 1
@@ -114,6 +116,7 @@ struct user_t
long unsigned ip; /* Ip address of user */
char hostname[MAX_HOST_LEN+1]; /* Hostname of user */
int type; /* Type of user, types defined above. */
+ int gag; /* If the user is gagged or not */
char nick[MAX_NICK_LEN+1]; /* Nickname of user */
char version[MAX_VERSION_LEN+1]; /* Version of client */
char *email; /* Email of user, optional */
diff --git a/src/xs_functions.c b/src/xs_functions.c
index e74bc4d..bfeb549 100644
--- a/src/xs_functions.c
+++ b/src/xs_functions.c
@@ -528,6 +528,24 @@ XS(xs_add_nickban_entry)
send_to_user("|", non_human_user_list);
}
+XS(xs_add_gag_entry)
+{
+ char *entry;
+ dXSARGS;
+
+ if(items != 1)
+ XSRETURN_UNDEF;
+
+ if(!SvPOK(ST(0)))
+ XSRETURN_UNDEF;
+
+ entry = SvPVX(ST(0));
+
+ send_to_user("$Gag ", non_human_user_list);
+ send_to_user(entry, non_human_user_list);
+ send_to_user("|", non_human_user_list);
+}
+
XS(xs_add_allow_entry)
{
char *entry;
@@ -600,6 +618,24 @@ XS(xs_remove_nickban_entry)
send_to_user("|", non_human_user_list);
}
+XS(xs_remove_gag_entry)
+{
+ char *entry;
+ dXSARGS;
+
+ if(items != 1)
+ XSRETURN_UNDEF;
+
+ if(!SvPOK(ST(0)))
+ XSRETURN_UNDEF;
+
+ entry = SvPVX(ST(0));
+
+ send_to_user("$UnGag ", non_human_user_list);
+ send_to_user(entry, non_human_user_list);
+ send_to_user("|", non_human_user_list);
+}
+
XS(xs_add_reg_user)
{
char *nick;
@@ -873,6 +909,9 @@ EXTERN_C void xs_init(void)
newXS("odch::check_if_banned", xs_check_if_banned, "xs_functions.c");
newXS("odch::check_if_allowed", xs_check_if_allowed, "xs_functions.c");
newXS("odch::data_to_user", xs_data_to_user, "xs_functions.c");
+ newXS("odch::gag_user", xs_add_gag_entry, "xs_functions.c");
+ newXS("odch::ungag_user", xs_remove_gag_entry, "xs_functions.c");
+ // newXS("odch::get_gag_list", xs_get_gag_list, "xs_functions.c");
newXS("odch::kick_user", xs_kick_user, "xs_functions.c");
newXS("odch::force_move_user", xs_force_move_user, "xs_functions.c");
newXS("odch::get_variable", xs_get_variable, "xs_functions.c");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment