mirror of
git://git.psyced.org/git/psyced
synced 2024-08-15 03:25:10 +00:00
178 lines
4.6 KiB
C
178 lines
4.6 KiB
C
|
// $Id: hosts.c,v 1.27 2008/03/11 13:42:25 lynx Exp $ // vim:syntax=lpc
|
||
|
//
|
||
|
// keeper of list of offensive hosts
|
||
|
|
||
|
#include <net.h>
|
||
|
#include CONFIG_PATH "hosts.h"
|
||
|
|
||
|
#ifdef legal_host
|
||
|
# undef legal_host
|
||
|
#endif
|
||
|
|
||
|
#ifndef DISABLED_HOSTS
|
||
|
# define DISABLED_HOSTS
|
||
|
#endif
|
||
|
#ifndef ENABLED_HOSTS
|
||
|
# define ENABLED_HOSTS
|
||
|
#endif
|
||
|
|
||
|
#ifdef PSYC_ENABLED_HOSTS
|
||
|
# define PSYC_TRUSTWORTHY_HOSTS PSYC_ENABLED_HOSTS
|
||
|
# define PSYC_PRIVATE
|
||
|
#endif
|
||
|
|
||
|
#define DATA_FILE DATA_PATH "hosts"
|
||
|
|
||
|
#define I_HOST 0
|
||
|
#define I_REASON 1
|
||
|
#define I_NEXT 2
|
||
|
|
||
|
array(string) disabled_hosts = ({ DISABLED_HOSTS });
|
||
|
mixed *disabled_list;
|
||
|
volatile array(string) enabled_hosts = ({ ENABLED_HOSTS });
|
||
|
volatile int loaded = 0;
|
||
|
|
||
|
#ifdef PSYC_TRUSTWORTHY_HOSTS
|
||
|
volatile array(string) psyc_trustworthy_hosts = ({ PSYC_TRUSTWORTHY_HOSTS });
|
||
|
#endif
|
||
|
|
||
|
create() { load(); }
|
||
|
|
||
|
load() {
|
||
|
// P1(("disabled_hosts is %O\n", disabled_hosts))
|
||
|
unless (loaded) {
|
||
|
loaded++;
|
||
|
restore_object(DATA_FILE);
|
||
|
unless (disabled_list) {
|
||
|
mixed *cur = disabled_list = allocate(3);
|
||
|
|
||
|
foreach (string host : disabled_hosts) {
|
||
|
cur = cur[I_NEXT] = allocate(3);
|
||
|
cur[I_HOST] = host;
|
||
|
// easier to read. no info where there is no info.
|
||
|
cur[I_REASON] = ""; // "Old block, no reason given.";
|
||
|
}
|
||
|
disabled_hosts = 0;
|
||
|
}
|
||
|
}
|
||
|
return ME;
|
||
|
}
|
||
|
|
||
|
legal_host(host, port, scheme, udp) {
|
||
|
int i, k, l;
|
||
|
mixed *cur = disabled_list;
|
||
|
|
||
|
if (udp) udp = 3; // UDP is spoofable, see net/psyc/udp.c
|
||
|
l = strlen(host);
|
||
|
P3(("legal_host(%O,%O,%O,%O) called\n", host, port, scheme, udp))
|
||
|
#ifdef PSYC_TRUSTWORTHY_HOSTS
|
||
|
if (scheme == "psyc") {
|
||
|
for (i=sizeof(psyc_trustworthy_hosts)-1; i>=0; i--) {
|
||
|
k = strlen(psyc_trustworthy_hosts[i]) - 1;
|
||
|
P3(("trustworthy_host(%O): %O,%O,%O,%O,%O\n",
|
||
|
host, i, k, l, psyc_trustworthy_hosts[i], host[0..k]))
|
||
|
if (k < l && host[0..k] == psyc_trustworthy_hosts[i])
|
||
|
return 9 - udp;
|
||
|
}
|
||
|
# ifdef PSYC_PRIVATE
|
||
|
return 0;
|
||
|
# endif
|
||
|
}
|
||
|
#endif
|
||
|
while (cur = cur[I_NEXT]) {
|
||
|
k = strlen(cur[I_HOST]) - 1;
|
||
|
P3(("disabled_host(%O): %O,%O,%O,%O,%O\n",
|
||
|
host, cur, k, l, cur[I_HOST], host[0..k]))
|
||
|
#if 1
|
||
|
// #define DIABLED_HOSTS "" blocks everyone.. imho this is not
|
||
|
// expected behaviour
|
||
|
if (k != -1 && k < l && host[0..k] == cur[I_HOST]) return 0;
|
||
|
#else // ungetestet.. wäre aber genauer
|
||
|
if (k < l && host[0..k] == cur[I_HOST]) {
|
||
|
if (host == cur[I_HOST]) return 0;
|
||
|
if (host[k] == '.') return 0;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
if (enabled_hosts && sizeof(enabled_hosts)) {
|
||
|
for (i=sizeof(enabled_hosts)-1; i>=0; i--) {
|
||
|
k = strlen(enabled_hosts[i]) - 1;
|
||
|
P4(("enabled_host(%O): %O,%O,%O,%O,%O\n",
|
||
|
host, i, k, l, enabled_hosts[i], host[0..k]))
|
||
|
if (k != -1 && k < l && host[0..k] == enabled_hosts[i])
|
||
|
return 7 - udp;
|
||
|
}
|
||
|
// why should activated ENABLED_HOSTS exclude everyone else??
|
||
|
//
|
||
|
// return 0;
|
||
|
}
|
||
|
return 5 - udp;
|
||
|
}
|
||
|
|
||
|
list() {
|
||
|
mapping show = ([ ]);
|
||
|
mixed *cur = disabled_list;
|
||
|
|
||
|
if (enabled_hosts && sizeof(enabled_hosts)) {
|
||
|
previous_object()->pr("_list_hosts_enabled_amount", // _tab
|
||
|
"Access permitted from %d IP nets\n", sizeof(enabled_hosts));
|
||
|
previous_object()->pr("_list_hosts_enabled", // _tab
|
||
|
"Enabled IP nets: %O\n", enabled_hosts);
|
||
|
}
|
||
|
/*
|
||
|
int i;
|
||
|
string l;
|
||
|
|
||
|
for (i=sizeof(disabled_hosts)-1; i>=0; i--) {
|
||
|
if (l) l += ", \""+ disabled_hosts[i] +"\"";
|
||
|
else l = "\""+ disabled_hosts[i] +"\"";
|
||
|
}
|
||
|
unless (l) l = "none.";
|
||
|
*/
|
||
|
while (cur = cur[I_NEXT])
|
||
|
show[cur[I_HOST]] = cur[I_REASON];
|
||
|
previous_object()->pr("_list_hosts_disabled", // _tab
|
||
|
"Blocked IP nets: %O\n", show);
|
||
|
// "Blocked IP nets: %-*#s\n", implode(disabled_hosts, "\n")
|
||
|
#ifdef PSYC_TRUSTWORTHY_HOSTS
|
||
|
previous_object()->pr("_list_hosts_trustworthy_psyc", // _tab
|
||
|
"PSYC-trustworthy nets: %O\n", psyc_trustworthy_hosts);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
modify(match, reason) {
|
||
|
int i;
|
||
|
mixed *pre, *cur = disabled_list;
|
||
|
|
||
|
//for (i=sizeof(disabled_hosts)-1; i>=0; i--) {
|
||
|
while ((pre = cur) && cur = cur[I_NEXT]) {
|
||
|
if (cur[I_HOST] == match) {
|
||
|
pre[I_NEXT] = cur[I_NEXT];
|
||
|
|
||
|
#ifdef SAVE_FORMAT
|
||
|
save_object(DATA_FILE, SAVE_FORMAT);
|
||
|
#else
|
||
|
save_object(DATA_FILE);
|
||
|
#endif
|
||
|
log_file("BLOCK", "[%s] %O unblocked by %O\n",
|
||
|
ctime(), match, previous_object());
|
||
|
monitor_report("_notice_block_off",
|
||
|
match+" unblocked by "+
|
||
|
object_name(previous_object()));
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
unless (reason) return -2;
|
||
|
disabled_list[I_NEXT] = ({ match, reason, disabled_list[I_NEXT] });
|
||
|
#ifdef SAVE_FORMAT
|
||
|
save_object(DATA_FILE, SAVE_FORMAT);
|
||
|
#else
|
||
|
save_object(DATA_FILE);
|
||
|
#endif
|
||
|
log_file("BLOCK", "[%s] %O blocked by %O\n",
|
||
|
ctime(), match, previous_object());
|
||
|
monitor_report("_notice_block_on",
|
||
|
match+" blocked by "+object_name(previous_object()));
|
||
|
return 1;
|
||
|
}
|