-
Notifications
You must be signed in to change notification settings - Fork 22
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
GanneffServ: make it possible to not kill irccloud #50
base: develop
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,6 +69,8 @@ def initialize() | |
["STATS", 0, 0, SFLG_NOMAXPARAM, ADMIN_FLAG, lm('GS_HLP_STS_SHORT'), lm('GS_HLP_STS_LONG')], | ||
["ENFORCE", 0, 0, SFLG_NOMAXPARAM, ADMIN_FLAG, lm('GS_HLP_ENF_SHORT'), lm('GS_HLP_ENF_LONG')], | ||
["BADSERV", 0, 1, SFLG_NOMAXPARAM, ADMIN_FLAG, lm('GS_HLP_SRV_SHORT'), lm('GS_HLP_SRV_LONG')], | ||
["PROTECT", 1, 2, SFLG_NOMAXPARAM, ADMIN_FLAG, lm('GS_HLP_PRT_SHORT'), lm('GS_HLP_PRT_LONG')], | ||
["UNPROTECT",1, 2, SFLG_NOMAXPARAM, ADMIN_FLAG, lm('GS_HLP_UPR_SHORT'), lm('GS_HLP_UPR_LONG')], | ||
]) # register | ||
|
||
# Which hooks do we want? | ||
|
@@ -100,6 +102,13 @@ def initialize() | |
irc_lower($1)') | ||
@dbq['INCREASE_KILLS'] = DB.prepare('UPDATE ganneffserv SET kills = kills+1 | ||
WHERE irc_lower(channel) = irc_lower($1)') | ||
@dbq['INSERT_PROTECT'] = DB.prepare('INSERT INTO ganneffprotect(setter, time, | ||
pattern, reason) VALUES($1, $2, $3, $4)') | ||
@dbq['DELETE_PROTECT'] = DB.prepare('DELETE FROM ganneffprotect WHERE | ||
irc_lower(pattern) = irc_lower($1)') | ||
@dbq['GET_PROTECTED_PATTERNS'] = DB.prepare('SELECT pattern, reason FROM ganneffprotect') | ||
@dbq['GET_PROTECTED_PATTERNS_DETAILED'] = DB.prepare('SELECT pattern, setter, time, | ||
reason FROM ganneffprotect') | ||
end # def initialize | ||
|
||
######################################################################## | ||
|
@@ -221,6 +230,50 @@ def DEL(client, parv = []) | |
true | ||
end # def DEL | ||
|
||
# ------------------------------------------------------------------------ | ||
|
||
# Protect users from collatoral damage | ||
def PROTECT(client, parv = []) | ||
parv[1].downcase! | ||
debug(LOG_DEBUG, "#{client.name} called PROTECT and the params are #{parv.join(",")}") | ||
|
||
requested_pattern = parv[1] | ||
pattern = irc_pattern_to_regex(requested_pattern) | ||
reason = parv[2] | ||
|
||
ret = DB.execute_nonquery(@dbq['INSERT_PROTECT'], 'iiss', client.nick.account_id, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put the original pattern in the DB, rather than the regex. This is important for the listing later, as looking at IRC masks is nicer than regexes, unless we've specifically given a regex. |
||
Time.now.to_i, pattern, reason) | ||
if ret then | ||
debug(LOG_NOTICE, "#{client.name} added protection #{pattern}, reason #{reason}") | ||
@protection[pattern] = reason | ||
load_protected_patterns | ||
reply(client, "Protection #{requested_pattern} successfully added") | ||
else | ||
reply(client, "Failed to add #{requested_pattern}") | ||
end | ||
end | ||
|
||
# ------------------------------------------------------------------------ | ||
|
||
# Unprotect users from collatoral damage | ||
def UNPROTECT(client, parv = []) | ||
parv[1].downcase! | ||
debug(LOG_DEBUG, "#{client.name} called UNPROTECT and the params are #{parv.join(",")}") | ||
|
||
pattern = irc_pattern_to_regex(parv[1]) | ||
return unless @protection.has_key?(pattern) | ||
|
||
ret = DB.execute_nonquery(@dbq['DELETE_PROTECT'], 's', pattern) | ||
if ret then | ||
debug(LOG_NOTICE, "#{client.name} removed protection #{pattern}") | ||
@protection.delete(pattern) | ||
load_protected_patterns | ||
reply(client, "Protection #{pattern} successfully deleted.") | ||
else | ||
reply(client, "Failed to delete protection #{pattern}.") | ||
end | ||
end | ||
|
||
# ------------------------------------------------------------------------ | ||
|
||
# List all channels we monitor | ||
|
@@ -245,6 +298,18 @@ def LIST(client, parv = []) | |
} | ||
result.free | ||
|
||
reply(client, "Protected host patterns\n\n") | ||
reply(client, "%-50s %-10s %-19s %s" % [ "Pattern", "By", "When", "Reason" ]) | ||
result = DB.execute(@dbq['GET_PROTECTED_PATTERNS_DETAILED']) | ||
result.row_each { |row| | ||
pattern = row[0] | ||
by = row[1] | ||
time = Time.at(row[2].to_i).strftime('%Y-%m-%d %H:%M:%S') | ||
reason = row[3] | ||
reply(client, "%-50s %-10s %-19s %s" % [ pattern, by, time, reason ]) | ||
} | ||
result.free | ||
|
||
reply(client, "\nCRFJ - checks Connect, Register nick, Join channel within 15 seconds (i.e. Fast)") | ||
reply(client, "J - triggers on every Join") | ||
|
||
|
@@ -326,7 +391,7 @@ def BADSERV(client, parv = []) | |
debug(LOG_DEBUG, "#{client.name} called BADSERV and the parms are #{parv.join(",")}") | ||
server = parv[1].downcase | ||
|
||
if server =~ /.*\.oftc.net$/ | ||
if server =~ /.*\.oftc\.net$/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is unrelated, but included because I was thinking about regular expressions while working on this file. It's an outlier in this file, everything else included the |
||
debug(LOG_DEBUG, "#{server} seems to be an oftc server, proceeding") | ||
@badserver = server | ||
reply(client, "#{server} is now marked as a bad server, all new connections will be killed") | ||
|
@@ -574,8 +639,13 @@ def akill(client, reason, operreason, channel="") | |
ret = kill_user(client, reason) | ||
else # if host | ||
reason = "#{reason}|#{operreason}" | ||
debug(LOG_DEBUG, "Issuing AKILL: *@#{host}, #{reason} lasting for #{@akill_duration} seconds") | ||
ret = akill_add("*@#{host}", reason, @akill_duration) | ||
if client.host =~ /#{@protected_patterns}/i # if protected hosts | ||
debug(LOG_DEBUG, "Using /kill instead of AKILL for protected user #{client.name}") | ||
ret = kill_user(client, reason) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This leaks the oper reason; kills don't hide oper reasons like akills do; easy fix is to just put this section as a branch in the enclosing if |
||
else | ||
debug(LOG_DEBUG, "Issuing AKILL: *@#{host}, #{reason} lasting for #{@akill_duration} seconds") | ||
ret = akill_add("*@#{host}", reason, @akill_duration) | ||
end # if protected hosts | ||
end # if host | ||
|
||
channel.downcase! | ||
|
@@ -596,6 +666,31 @@ def akill(client, reason, operreason, channel="") | |
end # if kill_user | ||
end # def akill | ||
|
||
# ------------------------------------------------------------------------ | ||
|
||
# convert irc pattern to regular expression | ||
def irc_pattern_to_regex(pattern | ||
# "." -> "\.", "*" -> ".*", "?" -> "." | ||
# wrap with "^...$" | ||
return pattern if pattern.start_with? '^' | ||
pattern = pattern.gsub(/\./, '\\.') | ||
.gsub(/\*/, '.*') | ||
.gsub(/\?/, '.') | ||
return "^#{pattern}$" | ||
end | ||
|
||
# ------------------------------------------------------------------------ | ||
|
||
# get protected patterns as pattern | ||
def load_protected_patterns() | ||
patterns = @protection.keys | ||
if patterns.empty? | ||
@protected_patterns = '^$' | ||
else | ||
@protected_patterns = patterns.join('|') | ||
end | ||
end # def get_protected_patterns | ||
|
||
# ------------------------------------------------------------------------ | ||
|
||
# enforce a channel - kill all of its users | ||
|
@@ -648,6 +743,20 @@ def load_data() | |
count += 1 | ||
} | ||
result.free | ||
|
||
@protection = Hash.new | ||
result = DB.execute(@dbq['GET_PROTECTED_PATTERNS'], '') | ||
count = 0 | ||
result.row_each { |row| | ||
pattern = row[0] | ||
reason = row[1] | ||
pattern = irc_pattern_to_regex(pattern) | ||
@protection[pattern] = reason | ||
count += 1 | ||
} | ||
result.free | ||
load_protected_patterns | ||
|
||
debug(LOG_DEBUG, "All channel data successfully loaded") | ||
end # def load_data | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setter
here will be an ID, not a name. Look atGET_ALL_CHANNELS
for a simple way to get the primary nick of the setting account.